Home | History | Annotate | Line # | Download | only in rsa
      1 /*
      2  * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (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 /*
     24  * RSA low level APIs are deprecated for public use, but still ok for
     25  * internal use.
     26  */
     27 #include "internal/deprecated.h"
     28 
     29 #include "internal/constant_time.h"
     30 
     31 #include <stdio.h>
     32 #include "internal/cryptlib.h"
     33 #include <openssl/bn.h>
     34 #include <openssl/evp.h>
     35 #include <openssl/rand.h>
     36 #include <openssl/sha.h>
     37 #include "rsa_local.h"
     38 
     39 int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
     40     const unsigned char *from, int flen,
     41     const unsigned char *param, int plen)
     42 {
     43     return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen,
     44         param, plen, NULL, NULL);
     45 }
     46 
     47 /*
     48  * Perform the padding as per NIST 800-56B 7.2.2.3
     49  *      from (K) is the key material.
     50  *      param (A) is the additional input.
     51  * Step numbers are included here but not in the constant time inverse below
     52  * to avoid complicating an already difficult enough function.
     53  */
     54 int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
     55     unsigned char *to, int tlen,
     56     const unsigned char *from, int flen,
     57     const unsigned char *param,
     58     int plen, const EVP_MD *md,
     59     const EVP_MD *mgf1md)
     60 {
     61     int rv = 0;
     62     int i, emlen = tlen - 1;
     63     unsigned char *db, *seed;
     64     unsigned char *dbmask = NULL;
     65     unsigned char seedmask[EVP_MAX_MD_SIZE];
     66     int mdlen, dbmask_len = 0;
     67 
     68     if (md == NULL) {
     69 #ifndef FIPS_MODULE
     70         md = EVP_sha1();
     71 #else
     72         ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
     73         return 0;
     74 #endif
     75     }
     76     if (mgf1md == NULL)
     77         mgf1md = md;
     78 
     79 #ifdef FIPS_MODULE
     80     /* XOF are approved as standalone; Shake256 in Ed448; MGF */
     81     if (EVP_MD_xof(md)) {
     82         ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
     83         return 0;
     84     }
     85     if (EVP_MD_xof(mgf1md)) {
     86         ERR_raise(ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED);
     87         return 0;
     88     }
     89 #endif
     90 
     91     mdlen = EVP_MD_get_size(md);
     92     if (mdlen <= 0) {
     93         ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_LENGTH);
     94         return 0;
     95     }
     96 
     97     /* step 2b: check KLen > nLen - 2 HLen - 2 */
     98     if (flen > emlen - 2 * mdlen - 1) {
     99         ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    100         return 0;
    101     }
    102 
    103     if (emlen < 2 * mdlen + 1) {
    104         ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL);
    105         return 0;
    106     }
    107 
    108     /* step 3i: EM = 00000000 || maskedMGF || maskedDB */
    109     to[0] = 0;
    110     seed = to + 1;
    111     db = to + mdlen + 1;
    112 
    113     /* step 3a: hash the additional input */
    114     if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
    115         goto err;
    116     /* step 3b: zero bytes array of length nLen - KLen - 2 HLen -2 */
    117     memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
    118     /* step 3c: DB = HA || PS || 00000001 || K */
    119     db[emlen - flen - mdlen - 1] = 0x01;
    120     memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
    121     /* step 3d: generate random byte string */
    122     if (RAND_bytes_ex(libctx, seed, mdlen, 0) <= 0)
    123         goto err;
    124 
    125     dbmask_len = emlen - mdlen;
    126     dbmask = OPENSSL_malloc(dbmask_len);
    127     if (dbmask == NULL)
    128         goto err;
    129 
    130     /* step 3e: dbMask = MGF(mgfSeed, nLen - HLen - 1) */
    131     if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0)
    132         goto err;
    133     /* step 3f: maskedDB = DB XOR dbMask */
    134     for (i = 0; i < dbmask_len; i++)
    135         db[i] ^= dbmask[i];
    136 
    137     /* step 3g: mgfSeed = MGF(maskedDB, HLen) */
    138     if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0)
    139         goto err;
    140     /* stepo 3h: maskedMGFSeed = mgfSeed XOR mgfSeedMask */
    141     for (i = 0; i < mdlen; i++)
    142         seed[i] ^= seedmask[i];
    143     rv = 1;
    144 
    145 err:
    146     OPENSSL_cleanse(seedmask, sizeof(seedmask));
    147     OPENSSL_clear_free(dbmask, dbmask_len);
    148     return rv;
    149 }
    150 
    151 int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
    152     const unsigned char *from, int flen,
    153     const unsigned char *param, int plen,
    154     const EVP_MD *md, const EVP_MD *mgf1md)
    155 {
    156     return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen,
    157         param, plen, md, mgf1md);
    158 }
    159 
    160 int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
    161     const unsigned char *from, int flen, int num,
    162     const unsigned char *param, int plen)
    163 {
    164     return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num,
    165         param, plen, NULL, NULL);
    166 }
    167 
    168 int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
    169     const unsigned char *from, int flen,
    170     int num, const unsigned char *param,
    171     int plen, const EVP_MD *md,
    172     const EVP_MD *mgf1md)
    173 {
    174     int i, dblen = 0, mlen = -1, one_index = 0, msg_index;
    175     unsigned int good = 0, found_one_byte, mask;
    176     const unsigned char *maskedseed, *maskeddb;
    177     /*
    178      * |em| is the encoded message, zero-padded to exactly |num| bytes: em =
    179      * Y || maskedSeed || maskedDB
    180      */
    181     unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
    182                   phash[EVP_MAX_MD_SIZE];
    183     int mdlen;
    184 
    185     if (md == NULL) {
    186 #ifndef FIPS_MODULE
    187         md = EVP_sha1();
    188 #else
    189         ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER);
    190         return -1;
    191 #endif
    192     }
    193 
    194     if (mgf1md == NULL)
    195         mgf1md = md;
    196 
    197 #ifdef FIPS_MODULE
    198     /* XOF are approved as standalone; Shake256 in Ed448; MGF */
    199     if (EVP_MD_xof(md)) {
    200         ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
    201         return -1;
    202     }
    203     if (EVP_MD_xof(mgf1md)) {
    204         ERR_raise(ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED);
    205         return -1;
    206     }
    207 #endif
    208 
    209     mdlen = EVP_MD_get_size(md);
    210 
    211     if (tlen <= 0 || flen <= 0 || mdlen <= 0)
    212         return -1;
    213     /*
    214      * |num| is the length of the modulus; |flen| is the length of the
    215      * encoded message. Therefore, for any |from| that was obtained by
    216      * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
    217      * |num| >= 2 * |mdlen| + 2 must hold for the modulus irrespective of
    218      * the ciphertext, see PKCS #1 v2.2, section 7.1.2.
    219      * This does not leak any side-channel information.
    220      */
    221     if (num < flen || num < 2 * mdlen + 2) {
    222         ERR_raise(ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR);
    223         return -1;
    224     }
    225 
    226     dblen = num - mdlen - 1;
    227     db = OPENSSL_malloc(dblen);
    228     if (db == NULL)
    229         goto cleanup;
    230 
    231     em = OPENSSL_malloc(num);
    232     if (em == NULL)
    233         goto cleanup;
    234 
    235     /*
    236      * Caller is encouraged to pass zero-padded message created with
    237      * BN_bn2binpad. Trouble is that since we can't read out of |from|'s
    238      * bounds, it's impossible to have an invariant memory access pattern
    239      * in case |from| was not zero-padded in advance.
    240      */
    241     for (from += flen, em += num, i = 0; i < num; i++) {
    242         mask = ~constant_time_is_zero(flen);
    243         flen -= 1 & mask;
    244         from -= 1 & mask;
    245         *--em = *from & mask;
    246     }
    247 
    248     /*
    249      * The first byte must be zero, however we must not leak if this is
    250      * true. See James H. Manger, "A Chosen Ciphertext  Attack on RSA
    251      * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
    252      */
    253     good = constant_time_is_zero(em[0]);
    254 
    255     maskedseed = em + 1;
    256     maskeddb = em + 1 + mdlen;
    257 
    258     if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
    259         goto cleanup;
    260     for (i = 0; i < mdlen; i++)
    261         seed[i] ^= maskedseed[i];
    262 
    263     if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
    264         goto cleanup;
    265     for (i = 0; i < dblen; i++)
    266         db[i] ^= maskeddb[i];
    267 
    268     if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
    269         goto cleanup;
    270 
    271     good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
    272 
    273     found_one_byte = 0;
    274     for (i = mdlen; i < dblen; i++) {
    275         /*
    276          * Padding consists of a number of 0-bytes, followed by a 1.
    277          */
    278         unsigned int equals1 = constant_time_eq(db[i], 1);
    279         unsigned int equals0 = constant_time_is_zero(db[i]);
    280         one_index = constant_time_select_int(~found_one_byte & equals1,
    281             i, one_index);
    282         found_one_byte |= equals1;
    283         good &= (found_one_byte | equals0);
    284     }
    285 
    286     good &= found_one_byte;
    287 
    288     /*
    289      * At this point |good| is zero unless the plaintext was valid,
    290      * so plaintext-awareness ensures timing side-channels are no longer a
    291      * concern.
    292      */
    293     msg_index = one_index + 1;
    294     mlen = dblen - msg_index;
    295 
    296     /*
    297      * For good measure, do this check in constant time as well.
    298      */
    299     good &= constant_time_ge(tlen, mlen);
    300 
    301     /*
    302      * Move the result in-place by |dblen|-|mdlen|-1-|mlen| bytes to the left.
    303      * Then if |good| move |mlen| bytes from |db|+|mdlen|+1 to |to|.
    304      * Otherwise leave |to| unchanged.
    305      * Copy the memory back in a way that does not reveal the size of
    306      * the data being copied via a timing side channel. This requires copying
    307      * parts of the buffer multiple times based on the bits set in the real
    308      * length. Clear bits do a non-copy with identical access pattern.
    309      * The loop below has overall complexity of O(N*log(N)).
    310      */
    311     tlen = constant_time_select_int(constant_time_lt(dblen - mdlen - 1, tlen),
    312         dblen - mdlen - 1, tlen);
    313     for (msg_index = 1; msg_index < dblen - mdlen - 1; msg_index <<= 1) {
    314         mask = ~constant_time_eq(msg_index & (dblen - mdlen - 1 - mlen), 0);
    315         for (i = mdlen + 1; i < dblen - msg_index; i++)
    316             db[i] = constant_time_select_8(mask, db[i + msg_index], db[i]);
    317     }
    318     for (i = 0; i < tlen; i++) {
    319         mask = good & constant_time_lt(i, mlen);
    320         to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]);
    321     }
    322 
    323 #ifndef FIPS_MODULE
    324     /*
    325      * To avoid chosen ciphertext attacks, the error message should not
    326      * reveal which kind of decoding error happened.
    327      *
    328      * This trick doesn't work in the FIPS provider because libcrypto manages
    329      * the error stack. Instead we opt not to put an error on the stack at all
    330      * in case of padding failure in the FIPS provider.
    331      */
    332     ERR_raise(ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR);
    333     err_clear_last_constant_time(1 & good);
    334 #endif
    335 cleanup:
    336     OPENSSL_cleanse(seed, sizeof(seed));
    337     OPENSSL_clear_free(db, dblen);
    338     OPENSSL_clear_free(em, num);
    339 
    340     return constant_time_select_int(good, mlen, -1);
    341 }
    342 
    343 /*
    344  * Mask Generation Function corresponding to section 7.2.2.2 of NIST SP 800-56B.
    345  * The variables are named differently to NIST:
    346  *      mask (T) and len (maskLen)are the returned mask.
    347  *      seed (mgfSeed).
    348  * The range checking steps inm the process are performed outside.
    349  */
    350 int PKCS1_MGF1(unsigned char *mask, long len,
    351     const unsigned char *seed, long seedlen, const EVP_MD *dgst)
    352 {
    353     long i, outlen = 0;
    354     unsigned char cnt[4];
    355     EVP_MD_CTX *c = EVP_MD_CTX_new();
    356     unsigned char md[EVP_MAX_MD_SIZE];
    357     int mdlen;
    358     int rv = -1;
    359 
    360     if (c == NULL)
    361         goto err;
    362     mdlen = EVP_MD_get_size(dgst);
    363     if (mdlen <= 0)
    364         goto err;
    365     /* step 4 */
    366     for (i = 0; outlen < len; i++) {
    367         /* step 4a: D = I2BS(counter, 4) */
    368         cnt[0] = (unsigned char)((i >> 24) & 255);
    369         cnt[1] = (unsigned char)((i >> 16) & 255);
    370         cnt[2] = (unsigned char)((i >> 8)) & 255;
    371         cnt[3] = (unsigned char)(i & 255);
    372         /* step 4b: T =T || hash(mgfSeed || D) */
    373         if (!EVP_DigestInit_ex(c, dgst, NULL)
    374             || !EVP_DigestUpdate(c, seed, seedlen)
    375             || !EVP_DigestUpdate(c, cnt, 4))
    376             goto err;
    377         if (outlen + mdlen <= len) {
    378             if (!EVP_DigestFinal_ex(c, mask + outlen, NULL))
    379                 goto err;
    380             outlen += mdlen;
    381         } else {
    382             if (!EVP_DigestFinal_ex(c, md, NULL))
    383                 goto err;
    384             memcpy(mask + outlen, md, len - outlen);
    385             outlen = len;
    386         }
    387     }
    388     rv = 0;
    389 err:
    390     OPENSSL_cleanse(md, sizeof(md));
    391     EVP_MD_CTX_free(c);
    392     return rv;
    393 }
    394