summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rsa/rsa_oaep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_oaep.c')
-rw-r--r--src/lib/libcrypto/rsa/rsa_oaep.c300
1 files changed, 169 insertions, 131 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c
index 1849e55cd5..e3f7c608ec 100644
--- a/src/lib/libcrypto/rsa/rsa_oaep.c
+++ b/src/lib/libcrypto/rsa/rsa_oaep.c
@@ -2,167 +2,205 @@
2/* Written by Ulf Moeller. This software is distributed on an "AS IS" 2/* Written by Ulf Moeller. This software is distributed on an "AS IS"
3 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */ 3 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
4 4
5/* EME_OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ 5/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
6 6
7#if !defined(NO_SHA) && !defined(NO_SHA1) 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)
8#include <stdio.h> 23#include <stdio.h>
9#include "cryptlib.h" 24#include "cryptlib.h"
10#include <openssl/bn.h> 25#include <openssl/bn.h>
11#include <openssl/rsa.h> 26#include <openssl/rsa.h>
12#include <openssl/sha.h> 27#include <openssl/evp.h>
13#include <openssl/rand.h> 28#include <openssl/rand.h>
29#include <openssl/sha.h>
14 30
15int MGF1(unsigned char *mask, long len, unsigned char *seed, long seedlen); 31int MGF1(unsigned char *mask, long len,
32 const unsigned char *seed, long seedlen);
16 33
17int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, 34int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
18 unsigned char *from, int flen, unsigned char *param, int plen) 35 const unsigned char *from, int flen,
19 { 36 const unsigned char *param, int plen)
20 int i, emlen = tlen - 1;
21 unsigned char *db, *seed;
22 unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
23
24 if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
25 { 37 {
26 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, 38 int i, emlen = tlen - 1;
27 RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 39 unsigned char *db, *seed;
28 return (0); 40 unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
29 }
30 41
31 if (emlen < 2 * SHA_DIGEST_LENGTH + 1) 42 if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
32 { 43 {
33 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL); 44 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
34 return (0); 45 RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
35 } 46 return 0;
36 47 }
37 dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH); 48
38 if (dbmask == NULL) 49 if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
39 { 50 {
40 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); 51 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
41 return (0); 52 return 0;
42 } 53 }
54
55 dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
56 if (dbmask == NULL)
57 {
58 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
59 return 0;
60 }
43 61
44 to[0] = 0; 62 to[0] = 0;
45 seed = to + 1; 63 seed = to + 1;
46 db = to + SHA_DIGEST_LENGTH + 1; 64 db = to + SHA_DIGEST_LENGTH + 1;
47 65
48 SHA1(param, plen, db); 66 EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
49 memset(db + SHA_DIGEST_LENGTH, 0, 67 memset(db + SHA_DIGEST_LENGTH, 0,
50 emlen - flen - 2 * SHA_DIGEST_LENGTH - 1); 68 emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
51 db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01; 69 db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
52 memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen); 70 memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
53 if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0) 71 if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
54 return (0); 72 return 0;
55#ifdef PKCS_TESTVECT 73#ifdef PKCS_TESTVECT
56 memcpy(seed, 74 memcpy(seed,
57 "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f", 75 "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
58 20); 76 20);
59#endif 77#endif
60 78
61 MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); 79 MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
62 for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) 80 for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
63 db[i] ^= dbmask[i]; 81 db[i] ^= dbmask[i];
64 82
65 MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); 83 MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
66 for (i = 0; i < SHA_DIGEST_LENGTH; i++) 84 for (i = 0; i < SHA_DIGEST_LENGTH; i++)
67 seed[i] ^= seedmask[i]; 85 seed[i] ^= seedmask[i];
68 86
69 OPENSSL_free(dbmask); 87 OPENSSL_free(dbmask);
70 return (1); 88 return 1;
71 } 89 }
72 90
73int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, 91int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
74 unsigned char *from, int flen, int num, unsigned char *param, 92 const unsigned char *from, int flen, int num,
75 int plen) 93 const unsigned char *param, int plen)
76 {
77 int i, dblen, mlen = -1;
78 unsigned char *maskeddb;
79 int lzero;
80 unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
81
82 if (--num < 2 * SHA_DIGEST_LENGTH + 1)
83 goto decoding_err;
84
85 lzero = num - flen;
86 if (lzero < 0)
87 goto decoding_err;
88 maskeddb = from - lzero + SHA_DIGEST_LENGTH;
89
90 dblen = num - SHA_DIGEST_LENGTH;
91 db = OPENSSL_malloc(dblen);
92 if (db == NULL)
93 { 94 {
94 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); 95 int i, dblen, mlen = -1;
95 return (-1); 96 const unsigned char *maskeddb;
96 } 97 int lzero;
98 unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
99 int bad = 0;
100
101 if (--num < 2 * SHA_DIGEST_LENGTH + 1)
102 /* 'num' is the length of the modulus, i.e. does not depend on the
103 * particular ciphertext. */
104 goto decoding_err;
105
106 lzero = num - flen;
107 if (lzero < 0)
108 {
109 /* lzero == -1 */
110
111 /* signalling this error immediately after detection might allow
112 * for side-channel attacks (e.g. timing if 'plen' is huge
113 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
114 * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
115 * so we use a 'bad' flag */
116 bad = 1;
117 lzero = 0;
118 }
119 maskeddb = from - lzero + SHA_DIGEST_LENGTH;
120
121 dblen = num - SHA_DIGEST_LENGTH;
122 db = OPENSSL_malloc(dblen);
123 if (db == NULL)
124 {
125 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
126 return -1;
127 }
97 128
98 MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); 129 MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
99 for (i = lzero; i < SHA_DIGEST_LENGTH; i++) 130 for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
100 seed[i] ^= from[i - lzero]; 131 seed[i] ^= from[i - lzero];
101 132
102 MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); 133 MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
103 for (i = 0; i < dblen; i++) 134 for (i = 0; i < dblen; i++)
104 db[i] ^= maskeddb[i]; 135 db[i] ^= maskeddb[i];
105 136
106 SHA1(param, plen, phash); 137 EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
107 138
108 if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0) 139 if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
109 goto decoding_err; 140 goto decoding_err;
110 else
111 {
112 for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
113 if (db[i] != 0x00)
114 break;
115 if (db[i] != 0x01 || i++ >= dblen)
116 goto decoding_err;
117 else 141 else
118 {
119 mlen = dblen - i;
120 if (tlen < mlen)
121 { 142 {
122 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE); 143 for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
123 mlen = -1; 144 if (db[i] != 0x00)
145 break;
146 if (db[i] != 0x01 || i++ >= dblen)
147 goto decoding_err;
148 else
149 {
150 /* everything looks OK */
151
152 mlen = dblen - i;
153 if (tlen < mlen)
154 {
155 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
156 mlen = -1;
157 }
158 else
159 memcpy(to, db + i, mlen);
160 }
124 } 161 }
125 else 162 OPENSSL_free(db);
126 memcpy(to, db + i, mlen); 163 return mlen;
127 }
128 }
129 OPENSSL_free(db);
130 return (mlen);
131 164
132decoding_err: 165decoding_err:
133 /* to avoid chosen ciphertext attacks, the error message should not reveal 166 /* to avoid chosen ciphertext attacks, the error message should not reveal
134 * which kind of decoding error happened */ 167 * which kind of decoding error happened */
135 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR); 168 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
136 if (db != NULL) OPENSSL_free(db); 169 if (db != NULL) OPENSSL_free(db);
137 return -1; 170 return -1;
138 } 171 }
139 172
140int MGF1(unsigned char *mask, long len, unsigned char *seed, long seedlen) 173int MGF1(unsigned char *mask, long len,
141 { 174 const unsigned char *seed, long seedlen)
142 long i, outlen = 0;
143 unsigned char cnt[4];
144 SHA_CTX c;
145 unsigned char md[SHA_DIGEST_LENGTH];
146
147 for (i = 0; outlen < len; i++)
148 { 175 {
149 cnt[0] = (i >> 24) & 255, cnt[1] = (i >> 16) & 255, 176 long i, outlen = 0;
150 cnt[2] = (i >> 8) & 255, cnt[3] = i & 255; 177 unsigned char cnt[4];
151 SHA1_Init(&c); 178 EVP_MD_CTX c;
152 SHA1_Update(&c, seed, seedlen); 179 unsigned char md[SHA_DIGEST_LENGTH];
153 SHA1_Update(&c, cnt, 4); 180
154 if (outlen + SHA_DIGEST_LENGTH <= len) 181 EVP_MD_CTX_init(&c);
155 { 182 for (i = 0; outlen < len; i++)
156 SHA1_Final(mask + outlen, &c); 183 {
157 outlen += SHA_DIGEST_LENGTH; 184 cnt[0] = (unsigned char)((i >> 24) & 255);
158 } 185 cnt[1] = (unsigned char)((i >> 16) & 255);
159 else 186 cnt[2] = (unsigned char)((i >> 8)) & 255;
160 { 187 cnt[3] = (unsigned char)(i & 255);
161 SHA1_Final(md, &c); 188 EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
162 memcpy(mask + outlen, md, len - outlen); 189 EVP_DigestUpdate(&c, seed, seedlen);
163 outlen = len; 190 EVP_DigestUpdate(&c, cnt, 4);
164 } 191 if (outlen + SHA_DIGEST_LENGTH <= len)
192 {
193 EVP_DigestFinal_ex(&c, mask + outlen, NULL);
194 outlen += SHA_DIGEST_LENGTH;
195 }
196 else
197 {
198 EVP_DigestFinal_ex(&c, md, NULL);
199 memcpy(mask + outlen, md, len - outlen);
200 outlen = len;
201 }
202 }
203 EVP_MD_CTX_cleanup(&c);
204 return 0;
165 } 205 }
166 return (0);
167 }
168#endif 206#endif