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