Branch data Line data Source code
1 : : /* crypto/rsa/rsa_oaep.c */
2 : : /* Written by Ulf Moeller. This software is distributed on an "AS IS"
3 : : basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
4 : :
5 : : /* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
6 : :
7 : : /* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
8 : : * <URL: http://www.shoup.net/papers/oaep.ps.Z>
9 : : * for problems with the security proof for the
10 : : * original OAEP scheme, which EME-OAEP is based on.
11 : : *
12 : : * A new proof can be found in E. Fujisaki, T. Okamoto,
13 : : * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
14 : : * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>.
15 : : * The new proof has stronger requirements for the
16 : : * underlying permutation: "partial-one-wayness" instead
17 : : * of one-wayness. For the RSA function, this is
18 : : * an equivalent notion.
19 : : */
20 : :
21 : : #define OPENSSL_FIPSAPI
22 : :
23 : :
24 : : #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
25 : : #include <stdio.h>
26 : : #include "cryptlib.h"
27 : : #include <openssl/bn.h>
28 : : #include <openssl/rsa.h>
29 : : #include <openssl/evp.h>
30 : : #include <openssl/rand.h>
31 : : #include <openssl/sha.h>
32 : :
33 : 6 : int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
34 : : const unsigned char *from, int flen,
35 : : const unsigned char *param, int plen)
36 : : {
37 : 6 : return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
38 : : param, plen, NULL, NULL);
39 : : }
40 : :
41 : 8 : int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
42 : : const unsigned char *from, int flen,
43 : : const unsigned char *param, int plen,
44 : : const EVP_MD *md, const EVP_MD *mgf1md)
45 : : {
46 : 8 : int i, emlen = tlen - 1;
47 : : unsigned char *db, *seed;
48 : : unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
49 : : int mdlen;
50 : :
51 [ + + ]: 8 : if (md == NULL)
52 : 6 : md = EVP_sha1();
53 [ + - ]: 8 : if (mgf1md == NULL)
54 : 8 : mgf1md = md;
55 : :
56 : 8 : mdlen = EVP_MD_size(md);
57 : :
58 [ - + ]: 8 : if (flen > emlen - 2 * mdlen - 1)
59 : : {
60 : 0 : RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
61 : : RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
62 : 0 : return 0;
63 : : }
64 : :
65 [ - + ]: 8 : if (emlen < 2 * mdlen + 1)
66 : : {
67 : 0 : RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, RSA_R_KEY_SIZE_TOO_SMALL);
68 : 0 : return 0;
69 : : }
70 : :
71 : 8 : to[0] = 0;
72 : 8 : seed = to + 1;
73 : 8 : db = to + mdlen + 1;
74 : :
75 [ + - ]: 8 : if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
76 : : return 0;
77 : 8 : memset(db + mdlen, 0,
78 : 8 : emlen - flen - 2 * mdlen - 1);
79 : 8 : db[emlen - flen - mdlen - 1] = 0x01;
80 : 8 : memcpy(db + emlen - flen - mdlen, from, (unsigned int) flen);
81 [ + - ]: 8 : if (RAND_bytes(seed, mdlen) <= 0)
82 : : return 0;
83 : : #ifdef PKCS_TESTVECT
84 : : memcpy(seed,
85 : : "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
86 : : 20);
87 : : #endif
88 : :
89 : 8 : dbmask = OPENSSL_malloc(emlen - mdlen);
90 [ - + ]: 8 : if (dbmask == NULL)
91 : : {
92 : 0 : RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
93 : 0 : return 0;
94 : : }
95 : :
96 [ + - ]: 8 : if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
97 : : return 0;
98 [ + + ]: 824 : for (i = 0; i < emlen - mdlen; i++)
99 : 816 : db[i] ^= dbmask[i];
100 : :
101 [ + - ]: 8 : if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
102 : : return 0;
103 [ + + ]: 180 : for (i = 0; i < mdlen; i++)
104 : 172 : seed[i] ^= seedmask[i];
105 : :
106 : 8 : OPENSSL_free(dbmask);
107 : 8 : return 1;
108 : : }
109 : :
110 : 18 : int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
111 : : const unsigned char *from, int flen, int num,
112 : : const unsigned char *param, int plen)
113 : : {
114 : 18 : return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from , flen, num,
115 : : param, plen,
116 : : NULL, NULL);
117 : : }
118 : :
119 : 20 : int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
120 : : const unsigned char *from, int flen, int num,
121 : : const unsigned char *param, int plen,
122 : : const EVP_MD *md, const EVP_MD *mgf1md)
123 : : {
124 : 20 : int i, dblen, mlen = -1;
125 : : const unsigned char *maskeddb;
126 : : int lzero;
127 : 20 : unsigned char *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
128 : : unsigned char *padded_from;
129 : 20 : int bad = 0;
130 : : int mdlen;
131 : :
132 [ + + ]: 20 : if (md == NULL)
133 : 18 : md = EVP_sha1();
134 [ + + ]: 20 : if (mgf1md == NULL)
135 : 18 : mgf1md = md;
136 : :
137 : 20 : mdlen = EVP_MD_size(md);
138 : :
139 [ + - ]: 20 : if (--num < 2 * mdlen + 1)
140 : : /* 'num' is the length of the modulus, i.e. does not depend on the
141 : : * particular ciphertext. */
142 : : goto decoding_err;
143 : :
144 : 20 : lzero = num - flen;
145 [ + + ]: 20 : if (lzero < 0)
146 : : {
147 : : /* signalling this error immediately after detection might allow
148 : : * for side-channel attacks (e.g. timing if 'plen' is huge
149 : : * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
150 : : * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
151 : : * so we use a 'bad' flag */
152 : 6 : bad = 1;
153 : 6 : lzero = 0;
154 : 6 : flen = num; /* don't overflow the memcpy to padded_from */
155 : : }
156 : :
157 : 20 : dblen = num - mdlen;
158 : 20 : db = OPENSSL_malloc(dblen + num);
159 [ - + ]: 20 : if (db == NULL)
160 : : {
161 : 0 : RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
162 : 0 : return -1;
163 : : }
164 : :
165 : : /* Always do this zero-padding copy (even when lzero == 0)
166 : : * to avoid leaking timing info about the value of lzero. */
167 : 20 : padded_from = db + dblen;
168 : 20 : memset(padded_from, 0, lzero);
169 : 20 : memcpy(padded_from + lzero, from, flen);
170 : :
171 : 20 : maskeddb = padded_from + mdlen;
172 : :
173 [ + - ]: 20 : if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
174 : : return -1;
175 [ + + ]: 432 : for (i = 0; i < mdlen; i++)
176 : 412 : seed[i] ^= padded_from[i];
177 : :
178 [ + - ]: 20 : if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
179 : : return -1;
180 [ + + ]: 1552 : for (i = 0; i < dblen; i++)
181 : 1532 : db[i] ^= maskeddb[i];
182 : :
183 [ + - ]: 20 : if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
184 : : return -1;
185 : :
186 [ + + ][ + - ]: 20 : if (CRYPTO_memcmp(db, phash, mdlen) != 0 || bad)
187 : : goto decoding_err;
188 : : else
189 : : {
190 [ + - ]: 738 : for (i = mdlen; i < dblen; i++)
191 [ + + ]: 738 : if (db[i] != 0x00)
192 : : break;
193 [ + - ][ + - ]: 14 : if (i == dblen || db[i] != 0x01)
194 : : goto decoding_err;
195 : : else
196 : : {
197 : : /* everything looks OK */
198 : :
199 : 14 : mlen = dblen - ++i;
200 [ - + ]: 14 : if (tlen < mlen)
201 : : {
202 : 0 : RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
203 : 0 : mlen = -1;
204 : : }
205 : : else
206 : 14 : memcpy(to, db + i, mlen);
207 : : }
208 : : }
209 : 14 : OPENSSL_free(db);
210 : 14 : return mlen;
211 : :
212 : : decoding_err:
213 : : /* to avoid chosen ciphertext attacks, the error message should not reveal
214 : : * which kind of decoding error happened */
215 : 6 : RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR);
216 [ + - ]: 6 : if (db != NULL) OPENSSL_free(db);
217 : : return -1;
218 : : }
219 : :
220 : 62 : int PKCS1_MGF1(unsigned char *mask, long len,
221 : : const unsigned char *seed, long seedlen, const EVP_MD *dgst)
222 : : {
223 : 62 : long i, outlen = 0;
224 : : unsigned char cnt[4];
225 : : EVP_MD_CTX c;
226 : : unsigned char md[EVP_MAX_MD_SIZE];
227 : : int mdlen;
228 : 62 : int rv = -1;
229 : :
230 : 62 : EVP_MD_CTX_init(&c);
231 : 62 : mdlen = M_EVP_MD_size(dgst);
232 [ + - ]: 62 : if (mdlen < 0)
233 : : goto err;
234 [ + + ]: 274 : for (i = 0; outlen < len; i++)
235 : : {
236 : 212 : cnt[0] = (unsigned char)((i >> 24) & 255);
237 : 212 : cnt[1] = (unsigned char)((i >> 16) & 255);
238 : 212 : cnt[2] = (unsigned char)((i >> 8)) & 255;
239 : 212 : cnt[3] = (unsigned char)(i & 255);
240 [ + - ]: 212 : if (!EVP_DigestInit_ex(&c,dgst, NULL)
241 [ + - ]: 212 : || !EVP_DigestUpdate(&c, seed, seedlen)
242 [ + - ]: 212 : || !EVP_DigestUpdate(&c, cnt, 4))
243 : : goto err;
244 [ + + ]: 212 : if (outlen + mdlen <= len)
245 : : {
246 [ + - ]: 178 : if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
247 : : goto err;
248 : : outlen += mdlen;
249 : : }
250 : : else
251 : : {
252 [ + - ]: 34 : if (!EVP_DigestFinal_ex(&c, md, NULL))
253 : : goto err;
254 : 34 : memcpy(mask + outlen, md, len - outlen);
255 : 34 : outlen = len;
256 : : }
257 : : }
258 : : rv = 0;
259 : : err:
260 : 62 : EVP_MD_CTX_cleanup(&c);
261 : 62 : return rv;
262 : : }
263 : :
264 : : #endif
|