diff options
author | Pauli <paul.dale@oracle.com> | 2019-04-17 14:24:26 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2019-04-17 14:26:11 +1000 |
commit | ad7e17dd6c8a3931da0fa9a06e80cf498278ef27 (patch) | |
tree | 79b77fce4b48f8bfec4c6a7ad97a0a6bb1317132 | |
parent | 06add280d90de9625e9c18985f376ef8d0419a46 (diff) |
SP 800-56B steps enumerated.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8770)
-rw-r--r-- | crypto/rsa/rsa_oaep.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index 9affabb99d..0945d4f60d 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -38,6 +38,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, param, plen, NULL, NULL); } +/* + * Perform ihe padding as per NIST 800-56B 7.2.2.3 + * from (K) is the key material. + * param (A) is the additional input. + * Step numbers are included here but not in the constant time inverse below + * to avoid complicating an already difficult enough function. + */ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, const unsigned char *from, int flen, const unsigned char *param, int plen, @@ -57,6 +64,7 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, mdlen = EVP_MD_size(md); + /* step 2b: check KLen > nLen - 2 HLen - 2 */ if (flen > emlen - 2 * mdlen - 1) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); @@ -69,15 +77,20 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, return 0; } + /* step 3i: EM = 00000000 || maskedMGF || maskedDB */ to[0] = 0; seed = to + 1; db = to + mdlen + 1; + /* step 3a: hash the additional input */ if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) goto err; + /* step 3b: zero bytes array of length nLen - KLen - 2 HLen -2 */ memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); + /* step 3c: DB = HA || PS || 00000001 || K */ db[emlen - flen - mdlen - 1] = 0x01; memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); + /* step 3d: generate random byte string */ if (RAND_bytes(seed, mdlen) <= 0) goto err; @@ -88,13 +101,17 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, goto err; } + /* step 3e: dbMask = MGF(mgfSeed, nLen - HLen - 1) */ if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) goto err; + /* step 3f: maskedDB = DB XOR dbMask */ for (i = 0; i < dbmask_len; i++) db[i] ^= dbmask[i]; + /* step 3g: mgfSeed = MGF(maskedDB, HLen) */ if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) goto err; + /* stepo 3h: maskedMGFSeed = mgfSeed XOR mgfSeedMask */ for (i = 0; i < mdlen; i++) seed[i] ^= seedmask[i]; rv = 1; @@ -270,6 +287,13 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, return constant_time_select_int(good, mlen, -1); } +/* + * Mask Generation Function corresponding to section 7.2.2.2 of NIST SP 800-56B. + * The variables are named differently to NIST: + * mask (T) and len (maskLen)are the returned mask. + * seed (mgfSeed). + * The range checking steps inm the process are performed outside. + */ int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD *dgst) { @@ -285,11 +309,14 @@ int PKCS1_MGF1(unsigned char *mask, long len, mdlen = EVP_MD_size(dgst); if (mdlen < 0) goto err; + /* step 4 */ for (i = 0; outlen < len; i++) { + /* step 4a: D = I2BS(counter, 4) */ cnt[0] = (unsigned char)((i >> 24) & 255); cnt[1] = (unsigned char)((i >> 16) & 255); cnt[2] = (unsigned char)((i >> 8)) & 255; cnt[3] = (unsigned char)(i & 255); + /* step 4b: T =T || hash(mgfSeed || D) */ if (!EVP_DigestInit_ex(c, dgst, NULL) || !EVP_DigestUpdate(c, seed, seedlen) || !EVP_DigestUpdate(c, cnt, 4)) |