5446d4db92d6a7512c4cc83726457f62af8651f9
[oweals/openssl.git] / crypto / rsa / rsa_oaep.c
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
22 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
23 #include <stdio.h>
24 #include "cryptlib.h"
25 #include <openssl/bn.h>
26 #include <openssl/rsa.h>
27 #include <openssl/evp.h>
28 #include <openssl/rand.h>
29 #include <openssl/sha.h>
30
31 int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
32         const unsigned char *from, int flen,
33         const unsigned char *param, int plen)
34         {
35         return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
36                                                 param, plen, NULL, NULL);
37         }
38
39 int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
40         const unsigned char *from, int flen,
41         const unsigned char *param, int plen,
42         const EVP_MD *md, const EVP_MD *mgf1md)
43         {
44         int i, emlen = tlen - 1;
45         unsigned char *db, *seed;
46         unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
47         int mdlen;
48
49         if (md == NULL)
50                 md = EVP_sha1();
51         if (mgf1md == NULL)
52                 mgf1md = md;
53
54         mdlen = EVP_MD_size(md);
55
56         if (flen > emlen - 2 * mdlen - 1)
57                 {
58                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
59                    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
60                 return 0;
61                 }
62
63         if (emlen < 2 * mdlen + 1)
64                 {
65                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, RSA_R_KEY_SIZE_TOO_SMALL);
66                 return 0;
67                 }
68
69         to[0] = 0;
70         seed = to + 1;
71         db = to + mdlen + 1;
72
73         if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
74                 return 0;
75         memset(db + mdlen, 0,
76                 emlen - flen - 2 * mdlen - 1);
77         db[emlen - flen - mdlen - 1] = 0x01;
78         memcpy(db + emlen - flen - mdlen, from, (unsigned int) flen);
79         if (RAND_bytes(seed, mdlen) <= 0)
80                 return 0;
81 #ifdef PKCS_TESTVECT
82         memcpy(seed,
83            "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
84            20);
85 #endif
86
87         dbmask = OPENSSL_malloc(emlen - mdlen);
88         if (dbmask == NULL)
89                 {
90                 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
91                 return 0;
92                 }
93
94         if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
95                 return 0;
96         for (i = 0; i < emlen - mdlen; i++)
97                 db[i] ^= dbmask[i];
98
99         if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
100                 return 0;
101         for (i = 0; i < mdlen; i++)
102                 seed[i] ^= seedmask[i];
103
104         OPENSSL_free(dbmask);
105         return 1;
106         }
107
108 int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
109         const unsigned char *from, int flen, int num,
110         const unsigned char *param, int plen)
111         {
112         return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from , flen, num,
113                                                         param, plen,
114                                                         NULL, NULL);
115         }
116
117 int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
118         const unsigned char *from, int flen, int num,
119         const unsigned char *param, int plen,
120         const EVP_MD *md, const EVP_MD *mgf1md)
121         {
122         int i, dblen, mlen = -1;
123         const unsigned char *maskeddb;
124         int lzero;
125         unsigned char *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
126         unsigned char *padded_from;
127         int bad = 0;
128         int mdlen;
129
130         if (md == NULL)
131                 md = EVP_sha1();
132         if (mgf1md == NULL)
133                 mgf1md = md;
134
135         mdlen = EVP_MD_size(md);
136
137         if (--num < 2 * mdlen + 1)
138                 /* 'num' is the length of the modulus, i.e. does not depend on the
139                  * particular ciphertext. */
140                 goto decoding_err;
141
142         lzero = num - flen;
143         if (lzero < 0)
144                 {
145                 /* signalling this error immediately after detection might allow
146                  * for side-channel attacks (e.g. timing if 'plen' is huge
147                  * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
148                  * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
149                  * so we use a 'bad' flag */
150                 bad = 1;
151                 lzero = 0;
152                 flen = num; /* don't overflow the memcpy to padded_from */
153                 }
154
155         dblen = num - mdlen;
156         db = OPENSSL_malloc(dblen + num);
157         if (db == NULL)
158                 {
159                 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
160                 return -1;
161                 }
162
163         /* Always do this zero-padding copy (even when lzero == 0)
164          * to avoid leaking timing info about the value of lzero. */
165         padded_from = db + dblen;
166         memset(padded_from, 0, lzero);
167         memcpy(padded_from + lzero, from, flen);
168
169         maskeddb = padded_from + mdlen;
170
171         if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
172                 return -1;
173         for (i = 0; i < mdlen; i++)
174                 seed[i] ^= padded_from[i];
175   
176         if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
177                 return -1;
178         for (i = 0; i < dblen; i++)
179                 db[i] ^= maskeddb[i];
180
181         if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
182                 return -1;
183
184         if (CRYPTO_memcmp(db, phash, mdlen) != 0 || bad)
185                 goto decoding_err;
186         else
187                 {
188                 for (i = mdlen; i < dblen; i++)
189                         if (db[i] != 0x00)
190                                 break;
191                 if (i == dblen || db[i] != 0x01)
192                         goto decoding_err;
193                 else
194                         {
195                         /* everything looks OK */
196
197                         mlen = dblen - ++i;
198                         if (tlen < mlen)
199                                 {
200                                 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
201                                 mlen = -1;
202                                 }
203                         else
204                                 memcpy(to, db + i, mlen);
205                         }
206                 }
207         OPENSSL_free(db);
208         return mlen;
209
210 decoding_err:
211         /* to avoid chosen ciphertext attacks, the error message should not reveal
212          * which kind of decoding error happened */
213         RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR);
214         if (db != NULL) OPENSSL_free(db);
215         return -1;
216         }
217
218 int PKCS1_MGF1(unsigned char *mask, long len,
219         const unsigned char *seed, long seedlen, const EVP_MD *dgst)
220         {
221         long i, outlen = 0;
222         unsigned char cnt[4];
223         EVP_MD_CTX c;
224         unsigned char md[EVP_MAX_MD_SIZE];
225         int mdlen;
226         int rv = -1;
227
228         EVP_MD_CTX_init(&c);
229         mdlen = EVP_MD_size(dgst);
230         if (mdlen < 0)
231                 goto err;
232         for (i = 0; outlen < len; i++)
233                 {
234                 cnt[0] = (unsigned char)((i >> 24) & 255);
235                 cnt[1] = (unsigned char)((i >> 16) & 255);
236                 cnt[2] = (unsigned char)((i >> 8)) & 255;
237                 cnt[3] = (unsigned char)(i & 255);
238                 if (!EVP_DigestInit_ex(&c,dgst, NULL)
239                         || !EVP_DigestUpdate(&c, seed, seedlen)
240                         || !EVP_DigestUpdate(&c, cnt, 4))
241                         goto err;
242                 if (outlen + mdlen <= len)
243                         {
244                         if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
245                                 goto err;
246                         outlen += mdlen;
247                         }
248                 else
249                         {
250                         if (!EVP_DigestFinal_ex(&c, md, NULL))
251                                 goto err;
252                         memcpy(mask + outlen, md, len - outlen);
253                         outlen = len;
254                         }
255                 }
256         rv = 0;
257         err:
258         EVP_MD_CTX_cleanup(&c);
259         return rv;
260         }
261
262 #endif