1 /* 2 * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ 11 12 /* 13 * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL: 14 * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security 15 * proof for the original OAEP scheme, which EME-OAEP is based on. A new 16 * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, 17 * "RSA-OEAP is Still Alive!", Dec. 2000, <URL: 18 * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements 19 * for the underlying permutation: "partial-one-wayness" instead of 20 * one-wayness. For the RSA function, this is an equivalent notion. 21 */ 22 23 #include "internal/constant_time_locl.h" 24 25 #include <stdio.h> 26 #include "internal/cryptlib.h" 27 #include <openssl/bn.h> 28 #include <openssl/evp.h> 29 #include <openssl/rand.h> 30 #include <openssl/sha.h> 31 #include "rsa_locl.h" 32 33 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 return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, 38 param, plen, NULL, NULL); 39 } 40 41 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 int rv = 0; 47 int i, emlen = tlen - 1; 48 unsigned char *db, *seed; 49 unsigned char *dbmask = NULL; 50 unsigned char seedmask[EVP_MAX_MD_SIZE]; 51 int mdlen, dbmask_len = 0; 52 53 if (md == NULL) 54 md = EVP_sha1(); 55 if (mgf1md == NULL) 56 mgf1md = md; 57 58 mdlen = EVP_MD_size(md); 59 60 if (flen > emlen - 2 * mdlen - 1) { 61 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 62 RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 63 return 0; 64 } 65 66 if (emlen < 2 * mdlen + 1) { 67 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 68 RSA_R_KEY_SIZE_TOO_SMALL); 69 return 0; 70 } 71 72 to[0] = 0; 73 seed = to + 1; 74 db = to + mdlen + 1; 75 76 if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) 77 goto err; 78 memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); 79 db[emlen - flen - mdlen - 1] = 0x01; 80 memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); 81 if (RAND_bytes(seed, mdlen) <= 0) 82 goto err; 83 84 dbmask_len = emlen - mdlen; 85 dbmask = OPENSSL_malloc(dbmask_len); 86 if (dbmask == NULL) { 87 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); 88 goto err; 89 } 90 91 if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) 92 goto err; 93 for (i = 0; i < dbmask_len; i++) 94 db[i] ^= dbmask[i]; 95 96 if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) 97 goto err; 98 for (i = 0; i < mdlen; i++) 99 seed[i] ^= seedmask[i]; 100 rv = 1; 101 102 err: 103 OPENSSL_cleanse(seedmask, sizeof(seedmask)); 104 OPENSSL_clear_free(dbmask, dbmask_len); 105 return rv; 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, NULL, NULL); 114 } 115 116 int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, 117 const unsigned char *from, int flen, 118 int num, const unsigned char *param, 119 int plen, const EVP_MD *md, 120 const EVP_MD *mgf1md) 121 { 122 int i, dblen = 0, mlen = -1, one_index = 0, msg_index; 123 unsigned int good, found_one_byte; 124 const unsigned char *maskedseed, *maskeddb; 125 /* 126 * |em| is the encoded message, zero-padded to exactly |num| bytes: em = 127 * Y || maskedSeed || maskedDB 128 */ 129 unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], 130 phash[EVP_MAX_MD_SIZE]; 131 int mdlen; 132 133 if (md == NULL) 134 md = EVP_sha1(); 135 if (mgf1md == NULL) 136 mgf1md = md; 137 138 mdlen = EVP_MD_size(md); 139 140 if (tlen <= 0 || flen <= 0) 141 return -1; 142 /* 143 * |num| is the length of the modulus; |flen| is the length of the 144 * encoded message. Therefore, for any |from| that was obtained by 145 * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, 146 * num < 2 * mdlen + 2 must hold for the modulus irrespective of 147 * the ciphertext, see PKCS #1 v2.2, section 7.1.2. 148 * This does not leak any side-channel information. 149 */ 150 if (num < flen || num < 2 * mdlen + 2) 151 goto decoding_err; 152 153 dblen = num - mdlen - 1; 154 db = OPENSSL_malloc(dblen); 155 if (db == NULL) { 156 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); 157 goto cleanup; 158 } 159 160 if (flen != num) { 161 em = OPENSSL_zalloc(num); 162 if (em == NULL) { 163 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 164 ERR_R_MALLOC_FAILURE); 165 goto cleanup; 166 } 167 168 /* 169 * Caller is encouraged to pass zero-padded message created with 170 * BN_bn2binpad, but if it doesn't, we do this zero-padding copy 171 * to avoid leaking that information. The copy still leaks some 172 * side-channel information, but it's impossible to have a fixed 173 * memory access pattern since we can't read out of the bounds of 174 * |from|. 175 */ 176 memcpy(em + num - flen, from, flen); 177 from = em; 178 } 179 180 /* 181 * The first byte must be zero, however we must not leak if this is 182 * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA 183 * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). 184 */ 185 good = constant_time_is_zero(from[0]); 186 187 maskedseed = from + 1; 188 maskeddb = from + 1 + mdlen; 189 190 if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) 191 goto cleanup; 192 for (i = 0; i < mdlen; i++) 193 seed[i] ^= maskedseed[i]; 194 195 if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) 196 goto cleanup; 197 for (i = 0; i < dblen; i++) 198 db[i] ^= maskeddb[i]; 199 200 if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) 201 goto cleanup; 202 203 good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); 204 205 found_one_byte = 0; 206 for (i = mdlen; i < dblen; i++) { 207 /* 208 * Padding consists of a number of 0-bytes, followed by a 1. 209 */ 210 unsigned int equals1 = constant_time_eq(db[i], 1); 211 unsigned int equals0 = constant_time_is_zero(db[i]); 212 one_index = constant_time_select_int(~found_one_byte & equals1, 213 i, one_index); 214 found_one_byte |= equals1; 215 good &= (found_one_byte | equals0); 216 } 217 218 good &= found_one_byte; 219 220 /* 221 * At this point |good| is zero unless the plaintext was valid, 222 * so plaintext-awareness ensures timing side-channels are no longer a 223 * concern. 224 */ 225 if (!good) 226 goto decoding_err; 227 228 msg_index = one_index + 1; 229 mlen = dblen - msg_index; 230 231 if (tlen < mlen) { 232 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE); 233 mlen = -1; 234 } else { 235 memcpy(to, db + msg_index, mlen); 236 goto cleanup; 237 } 238 239 decoding_err: 240 /* 241 * To avoid chosen ciphertext attacks, the error message should not 242 * reveal which kind of decoding error happened. 243 */ 244 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 245 RSA_R_OAEP_DECODING_ERROR); 246 cleanup: 247 OPENSSL_cleanse(seed, sizeof(seed)); 248 OPENSSL_clear_free(db, dblen); 249 OPENSSL_clear_free(em, num); 250 return mlen; 251 } 252 253 int PKCS1_MGF1(unsigned char *mask, long len, 254 const unsigned char *seed, long seedlen, const EVP_MD *dgst) 255 { 256 long i, outlen = 0; 257 unsigned char cnt[4]; 258 EVP_MD_CTX *c = EVP_MD_CTX_new(); 259 unsigned char md[EVP_MAX_MD_SIZE]; 260 int mdlen; 261 int rv = -1; 262 263 if (c == NULL) 264 goto err; 265 mdlen = EVP_MD_size(dgst); 266 if (mdlen < 0) 267 goto err; 268 for (i = 0; outlen < len; i++) { 269 cnt[0] = (unsigned char)((i >> 24) & 255); 270 cnt[1] = (unsigned char)((i >> 16) & 255); 271 cnt[2] = (unsigned char)((i >> 8)) & 255; 272 cnt[3] = (unsigned char)(i & 255); 273 if (!EVP_DigestInit_ex(c, dgst, NULL) 274 || !EVP_DigestUpdate(c, seed, seedlen) 275 || !EVP_DigestUpdate(c, cnt, 4)) 276 goto err; 277 if (outlen + mdlen <= len) { 278 if (!EVP_DigestFinal_ex(c, mask + outlen, NULL)) 279 goto err; 280 outlen += mdlen; 281 } else { 282 if (!EVP_DigestFinal_ex(c, md, NULL)) 283 goto err; 284 memcpy(mask + outlen, md, len - outlen); 285 outlen = len; 286 } 287 } 288 rv = 0; 289 err: 290 OPENSSL_cleanse(md, sizeof(md)); 291 EVP_MD_CTX_free(c); 292 return rv; 293 } 294