diff options
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_oaep.c')
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_oaep.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c index 3652677a99..d43ecaca63 100644 --- a/src/lib/libcrypto/rsa/rsa_oaep.c +++ b/src/lib/libcrypto/rsa/rsa_oaep.c | |||
@@ -28,9 +28,6 @@ | |||
28 | #include <openssl/rand.h> | 28 | #include <openssl/rand.h> |
29 | #include <openssl/sha.h> | 29 | #include <openssl/sha.h> |
30 | 30 | ||
31 | int MGF1(unsigned char *mask, long len, | ||
32 | const unsigned char *seed, long seedlen); | ||
33 | |||
34 | int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, | 31 | int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, |
35 | const unsigned char *from, int flen, | 32 | const unsigned char *from, int flen, |
36 | const unsigned char *param, int plen) | 33 | const unsigned char *param, int plen) |
@@ -76,11 +73,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, | |||
76 | 20); | 73 | 20); |
77 | #endif | 74 | #endif |
78 | 75 | ||
79 | MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); | 76 | PKCS1_MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH, |
77 | EVP_sha1()); | ||
80 | for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) | 78 | for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) |
81 | db[i] ^= dbmask[i]; | 79 | db[i] ^= dbmask[i]; |
82 | 80 | ||
83 | MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); | 81 | PKCS1_MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH, |
82 | EVP_sha1()); | ||
84 | for (i = 0; i < SHA_DIGEST_LENGTH; i++) | 83 | for (i = 0; i < SHA_DIGEST_LENGTH; i++) |
85 | seed[i] ^= seedmask[i]; | 84 | seed[i] ^= seedmask[i]; |
86 | 85 | ||
@@ -96,7 +95,6 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | |||
96 | const unsigned char *maskeddb; | 95 | const unsigned char *maskeddb; |
97 | int lzero; | 96 | int lzero; |
98 | unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH]; | 97 | unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH]; |
99 | unsigned char *padded_from; | ||
100 | int bad = 0; | 98 | int bad = 0; |
101 | 99 | ||
102 | if (--num < 2 * SHA_DIGEST_LENGTH + 1) | 100 | if (--num < 2 * SHA_DIGEST_LENGTH + 1) |
@@ -107,6 +105,8 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | |||
107 | lzero = num - flen; | 105 | lzero = num - flen; |
108 | if (lzero < 0) | 106 | if (lzero < 0) |
109 | { | 107 | { |
108 | /* lzero == -1 */ | ||
109 | |||
110 | /* signalling this error immediately after detection might allow | 110 | /* signalling this error immediately after detection might allow |
111 | * for side-channel attacks (e.g. timing if 'plen' is huge | 111 | * for side-channel attacks (e.g. timing if 'plen' is huge |
112 | * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal | 112 | * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal |
@@ -114,30 +114,22 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | |||
114 | * so we use a 'bad' flag */ | 114 | * so we use a 'bad' flag */ |
115 | bad = 1; | 115 | bad = 1; |
116 | lzero = 0; | 116 | lzero = 0; |
117 | flen = num; /* don't overflow the memcpy to padded_from */ | ||
118 | } | 117 | } |
118 | maskeddb = from - lzero + SHA_DIGEST_LENGTH; | ||
119 | 119 | ||
120 | dblen = num - SHA_DIGEST_LENGTH; | 120 | dblen = num - SHA_DIGEST_LENGTH; |
121 | db = OPENSSL_malloc(dblen + num); | 121 | db = OPENSSL_malloc(dblen); |
122 | if (db == NULL) | 122 | if (db == NULL) |
123 | { | 123 | { |
124 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); | 124 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); |
125 | return -1; | 125 | return -1; |
126 | } | 126 | } |
127 | 127 | ||
128 | /* Always do this zero-padding copy (even when lzero == 0) | 128 | PKCS1_MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen, EVP_sha1()); |
129 | * to avoid leaking timing info about the value of lzero. */ | 129 | for (i = lzero; i < SHA_DIGEST_LENGTH; i++) |
130 | padded_from = db + dblen; | 130 | seed[i] ^= from[i - lzero]; |
131 | memset(padded_from, 0, lzero); | ||
132 | memcpy(padded_from + lzero, from, flen); | ||
133 | |||
134 | maskeddb = padded_from + SHA_DIGEST_LENGTH; | ||
135 | |||
136 | MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); | ||
137 | for (i = 0; i < SHA_DIGEST_LENGTH; i++) | ||
138 | seed[i] ^= padded_from[i]; | ||
139 | 131 | ||
140 | MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); | 132 | PKCS1_MGF1(db, dblen, seed, SHA_DIGEST_LENGTH, EVP_sha1()); |
141 | for (i = 0; i < dblen; i++) | 133 | for (i = 0; i < dblen; i++) |
142 | db[i] ^= maskeddb[i]; | 134 | db[i] ^= maskeddb[i]; |
143 | 135 | ||
@@ -150,13 +142,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | |||
150 | for (i = SHA_DIGEST_LENGTH; i < dblen; i++) | 142 | for (i = SHA_DIGEST_LENGTH; i < dblen; i++) |
151 | if (db[i] != 0x00) | 143 | if (db[i] != 0x00) |
152 | break; | 144 | break; |
153 | if (i == dblen || db[i] != 0x01) | 145 | if (db[i] != 0x01 || i++ >= dblen) |
154 | goto decoding_err; | 146 | goto decoding_err; |
155 | else | 147 | else |
156 | { | 148 | { |
157 | /* everything looks OK */ | 149 | /* everything looks OK */ |
158 | 150 | ||
159 | mlen = dblen - ++i; | 151 | mlen = dblen - i; |
160 | if (tlen < mlen) | 152 | if (tlen < mlen) |
161 | { | 153 | { |
162 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE); | 154 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE); |