1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2021 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * 8*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 9*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 10*f0865ec9SKyle Evans */ 11*f0865ec9SKyle Evans #include "rsa.h" 12*f0865ec9SKyle Evans #include "rsa_tests.h" 13*f0865ec9SKyle Evans 14*f0865ec9SKyle Evans 15*f0865ec9SKyle Evans /* We include the rand external dependency because we have to generate 16*f0865ec9SKyle Evans * some random data for the padding. 17*f0865ec9SKyle Evans */ 18*f0865ec9SKyle Evans #include <libecc/external_deps/rand.h> 19*f0865ec9SKyle Evans /* We include the printf external dependency for printf output */ 20*f0865ec9SKyle Evans #include <libecc/external_deps/print.h> 21*f0865ec9SKyle Evans /* We include our common helpers */ 22*f0865ec9SKyle Evans #include "../common/common.h" 23*f0865ec9SKyle Evans 24*f0865ec9SKyle Evans 25*f0865ec9SKyle Evans /* 26*f0865ec9SKyle Evans * The purpose of this example is to implement the RSA 27*f0865ec9SKyle Evans * related algorithms as per RFC 8017 and ISO/IEC 9796-2 based 28*f0865ec9SKyle Evans * on libecc arithmetic primitives. 29*f0865ec9SKyle Evans * 30*f0865ec9SKyle Evans * XXX: Please be aware that libecc has been designed for Elliptic 31*f0865ec9SKyle Evans * Curve cryptography, and as so the arithmetic primitives are 32*f0865ec9SKyle Evans * not optimized for big numbers >= 1024 bits usually used for RSA. 33*f0865ec9SKyle Evans * Additionnaly, a hard limit of our NN values makes it impossible 34*f0865ec9SKyle Evans * to exceed ~5300 bits in the best case (words of size 64 bits). 35*f0865ec9SKyle Evans * 36*f0865ec9SKyle Evans * All in all, please see this as a proof of concept of implementing 37*f0865ec9SKyle Evans * RFC 8017 rather than a production code. Use it at your own risk! 38*f0865ec9SKyle Evans * 39*f0865ec9SKyle Evans * !! DISCLAIMER !! 40*f0865ec9SKyle Evans * ================ 41*f0865ec9SKyle Evans * Although some efforts have been put on providing a clean code and although many of 42*f0865ec9SKyle Evans * the underlying arithmetic primitives are constant time, only basic efforts have 43*f0865ec9SKyle Evans * been deployed to prevent advanced side channels (e.g. to protect the private values 44*f0865ec9SKyle Evans * against elaborate microarchitectural side-channels and so on). The modular exponentation 45*f0865ec9SKyle Evans * uses a Montgomery Ladder, and message blinding is performed to mitigate basic SCA. 46*f0865ec9SKyle Evans * Please note that the modular exponentation is NOT constant time wrt the MSB of 47*f0865ec9SKyle Evans * the private exponent, which should be OK in the general case as this leak is less 48*f0865ec9SKyle Evans * critical than for DSA and ECDSA nonces in scalar multiplication (raising HNP issues 49*f0865ec9SKyle Evans * in these last cases). 50*f0865ec9SKyle Evans * Optionally, when BLINDING=1 is activated, exponent blinding is used by adding a 51*f0865ec9SKyle Evans * "small" (128 bits) multiple of the "order" (this is left as optional because of 52*f0865ec9SKyle Evans * the big impacts on performance), somehow limiting the modular exponentiation MSB 53*f0865ec9SKyle Evans * issue at the expense of performance. 54*f0865ec9SKyle Evans * 55*f0865ec9SKyle Evans * Padding oracles (Bleichenbacher, Manger) in RSA PKCS#1 v1.5 and RSA-OAEP decryption 56*f0865ec9SKyle Evans * primitives are taken into account, although no absolute guarantee can be made on this 57*f0865ec9SKyle Evans * (and mostly: these oracles also heavily depend on what the upper layer callers do). 58*f0865ec9SKyle Evans * 59*f0865ec9SKyle Evans * Fault injection attacks "a la Bellcore" are protected using a sanity check that 60*f0865ec9SKyle Evans * the exponentiation to the public exponent provides the same input as the operation 61*f0865ec9SKyle Evans * using the private exponent. 62*f0865ec9SKyle Evans * 63*f0865ec9SKyle Evans * !!NOTE: only the *_hardened* suffixed APIs are protected, the non suffixed ones are 64*f0865ec9SKyle Evans * *NOT* protected. This is mainly due to the fact that the protections use the public 65*f0865ec9SKyle Evans * key while the RFC APIs handling private operations only take the private key as 66*f0865ec9SKyle Evans * input. Hence, please *USE* the *_hardened* APIs if unsure about your usage context! 67*f0865ec9SKyle Evans * 68*f0865ec9SKyle Evans * Also, as for all other libecc primitives, beware of randomness sources. By default, 69*f0865ec9SKyle Evans * the library uses the OS random sources (e.g. "/dev/urandom"), but the user 70*f0865ec9SKyle Evans * is encouraged to adapt the ../external_deps/rand.c source file to combine 71*f0865ec9SKyle Evans * multiple sources and add entropy there depending on the context where this 72*f0865ec9SKyle Evans * code is integrated. The security level of all the cryptographic primitives 73*f0865ec9SKyle Evans * heavily relies on random sources quality. 74*f0865ec9SKyle Evans * 75*f0865ec9SKyle Evans * All-in-all, this piece of code can be useful in some contexts, or risky to 76*f0865ec9SKyle Evans * use in other sensitive ones where advanced side-channels or fault attacks 77*f0865ec9SKyle Evans * have to be considered. Use this RSA code knowingly and at your own risk! 78*f0865ec9SKyle Evans * 79*f0865ec9SKyle Evans */ 80*f0865ec9SKyle Evans 81*f0865ec9SKyle Evans int rsa_import_pub_key(rsa_pub_key *pub, const u8 *n, 82*f0865ec9SKyle Evans u16 nlen, const u8 *e, u16 elen) 83*f0865ec9SKyle Evans { 84*f0865ec9SKyle Evans int ret; 85*f0865ec9SKyle Evans 86*f0865ec9SKyle Evans MUST_HAVE((pub != NULL), ret, err); 87*f0865ec9SKyle Evans 88*f0865ec9SKyle Evans /* Import our big numbers */ 89*f0865ec9SKyle Evans ret = nn_init_from_buf(&(pub->n), n, nlen); EG(ret, err); 90*f0865ec9SKyle Evans ret = nn_init_from_buf(&(pub->e), e, elen); 91*f0865ec9SKyle Evans 92*f0865ec9SKyle Evans err: 93*f0865ec9SKyle Evans if(ret && (pub != NULL)){ 94*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(pub, 0, sizeof(rsa_pub_key))); 95*f0865ec9SKyle Evans } 96*f0865ec9SKyle Evans 97*f0865ec9SKyle Evans return ret; 98*f0865ec9SKyle Evans } 99*f0865ec9SKyle Evans 100*f0865ec9SKyle Evans int rsa_import_simple_priv_key(rsa_priv_key *priv, 101*f0865ec9SKyle Evans const u8 *n, u16 nlen, const u8 *d, u16 dlen, 102*f0865ec9SKyle Evans const u8 *p, u16 plen, const u8 *q, u16 qlen) 103*f0865ec9SKyle Evans { 104*f0865ec9SKyle Evans int ret; 105*f0865ec9SKyle Evans 106*f0865ec9SKyle Evans MUST_HAVE((priv != NULL), ret, err); 107*f0865ec9SKyle Evans 108*f0865ec9SKyle Evans MUST_HAVE(((p != NULL) && (q != NULL)) || ((p == NULL) && (q == NULL)), ret, err); 109*f0865ec9SKyle Evans 110*f0865ec9SKyle Evans /* Import our big numbers */ 111*f0865ec9SKyle Evans if((p == NULL) || (q == NULL)){ 112*f0865ec9SKyle Evans priv->type = RSA_SIMPLE; 113*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s.n), n, nlen); EG(ret, err); 114*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s.d), d, dlen); EG(ret, err); 115*f0865ec9SKyle Evans } 116*f0865ec9SKyle Evans else{ 117*f0865ec9SKyle Evans priv->type = RSA_SIMPLE_PQ; 118*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s_pq.n), n, nlen); EG(ret, err); 119*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s_pq.d), d, dlen); EG(ret, err); 120*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s_pq.p), p, plen); EG(ret, err); 121*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.s_pq.q), q, qlen); EG(ret, err); 122*f0865ec9SKyle Evans } 123*f0865ec9SKyle Evans 124*f0865ec9SKyle Evans err: 125*f0865ec9SKyle Evans if(ret && (priv != NULL)){ 126*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(priv, 0, sizeof(rsa_priv_key))); 127*f0865ec9SKyle Evans } 128*f0865ec9SKyle Evans 129*f0865ec9SKyle Evans return ret; 130*f0865ec9SKyle Evans } 131*f0865ec9SKyle Evans 132*f0865ec9SKyle Evans int rsa_import_crt_priv_key(rsa_priv_key *priv, 133*f0865ec9SKyle Evans const u8 *p, u16 plen, 134*f0865ec9SKyle Evans const u8 *q, u16 qlen, 135*f0865ec9SKyle Evans const u8 *dP, u16 dPlen, 136*f0865ec9SKyle Evans const u8 *dQ, u16 dQlen, 137*f0865ec9SKyle Evans const u8 *qInv, u16 qInvlen, 138*f0865ec9SKyle Evans const u8 **coeffs, u16 *coeffslens, u8 u) 139*f0865ec9SKyle Evans { 140*f0865ec9SKyle Evans int ret; 141*f0865ec9SKyle Evans 142*f0865ec9SKyle Evans MUST_HAVE((priv != NULL), ret, err); 143*f0865ec9SKyle Evans 144*f0865ec9SKyle Evans priv->type = RSA_CRT; 145*f0865ec9SKyle Evans /* Import our big numbers */ 146*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.crt.p), p, plen); EG(ret, err); 147*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.crt.q), q, qlen); EG(ret, err); 148*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.crt.dP), dP, dPlen); EG(ret, err); 149*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.crt.dQ), dQ, dQlen); EG(ret, err); 150*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv->key.crt.qInv), qInv, qInvlen); EG(ret, err); 151*f0865ec9SKyle Evans 152*f0865ec9SKyle Evans priv->key.crt.u = 0; 153*f0865ec9SKyle Evans 154*f0865ec9SKyle Evans /* Import the optional coefficients if necessary */ 155*f0865ec9SKyle Evans if(coeffs != NULL){ 156*f0865ec9SKyle Evans unsigned int i; 157*f0865ec9SKyle Evans 158*f0865ec9SKyle Evans MUST_HAVE((coeffslens != NULL), ret, err); 159*f0865ec9SKyle Evans MUST_HAVE((u > 0) && (u < MAX_CRT_COEFFS), ret, err); 160*f0865ec9SKyle Evans 161*f0865ec9SKyle Evans priv->key.crt.u = u; 162*f0865ec9SKyle Evans 163*f0865ec9SKyle Evans for(i = 0; i < (3*u); i += 3){ 164*f0865ec9SKyle Evans rsa_priv_key_crt_coeffs *cur = &(priv->key.crt.coeffs[(i / 3)]); 165*f0865ec9SKyle Evans 166*f0865ec9SKyle Evans ret = nn_init_from_buf(&(cur->r), coeffs[i], coeffslens[i]); EG(ret, err); 167*f0865ec9SKyle Evans ret = nn_init_from_buf(&(cur->d), coeffs[i + 1], coeffslens[i + 1]); EG(ret, err); 168*f0865ec9SKyle Evans ret = nn_init_from_buf(&(cur->t), coeffs[i + 2], coeffslens[i + 2]); EG(ret, err); 169*f0865ec9SKyle Evans } 170*f0865ec9SKyle Evans } 171*f0865ec9SKyle Evans 172*f0865ec9SKyle Evans err: 173*f0865ec9SKyle Evans if(ret && (priv != NULL)){ 174*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(priv, 0, sizeof(rsa_priv_key))); 175*f0865ec9SKyle Evans } 176*f0865ec9SKyle Evans return ret; 177*f0865ec9SKyle Evans } 178*f0865ec9SKyle Evans 179*f0865ec9SKyle Evans /* I2OSP - Integer-to-Octet-String primitive 180*f0865ec9SKyle Evans * (as decribed in section 4.1 of RFC 8017) 181*f0865ec9SKyle Evans */ 182*f0865ec9SKyle Evans int rsa_i2osp(nn_src_t x, u8 *buf, u32 buflen) 183*f0865ec9SKyle Evans { 184*f0865ec9SKyle Evans int ret; 185*f0865ec9SKyle Evans 186*f0865ec9SKyle Evans /* Size check */ 187*f0865ec9SKyle Evans MUST_HAVE((buflen <= 0xffff), ret, err); 188*f0865ec9SKyle Evans ret = _i2osp(x, buf, (u16)buflen); 189*f0865ec9SKyle Evans 190*f0865ec9SKyle Evans err: 191*f0865ec9SKyle Evans return ret; 192*f0865ec9SKyle Evans } 193*f0865ec9SKyle Evans 194*f0865ec9SKyle Evans /* OS2IP - Octet-String-to-Integer primitive 195*f0865ec9SKyle Evans * (as decribed in section 4.2 of RFC 8017) 196*f0865ec9SKyle Evans */ 197*f0865ec9SKyle Evans int rsa_os2ip(nn_t x, const u8 *buf, u32 buflen) 198*f0865ec9SKyle Evans { 199*f0865ec9SKyle Evans int ret; 200*f0865ec9SKyle Evans 201*f0865ec9SKyle Evans /* Size check */ 202*f0865ec9SKyle Evans MUST_HAVE((buflen <= 0xffff), ret, err); 203*f0865ec9SKyle Evans ret = _os2ip(x, buf, (u16)buflen); 204*f0865ec9SKyle Evans 205*f0865ec9SKyle Evans err: 206*f0865ec9SKyle Evans return ret; 207*f0865ec9SKyle Evans } 208*f0865ec9SKyle Evans 209*f0865ec9SKyle Evans /* The raw RSAEP function as defined in RFC 8017 section 5.1.1 210*f0865ec9SKyle Evans * Input: an RSA public key and a big int message 211*f0865ec9SKyle Evans * Output: a big int ciphertext 212*f0865ec9SKyle Evans * Assumption: RSA public key K is valid 213*f0865ec9SKyle Evans */ 214*f0865ec9SKyle Evans int rsaep(const rsa_pub_key *pub, nn_src_t m, nn_t c) 215*f0865ec9SKyle Evans { 216*f0865ec9SKyle Evans int ret, cmp; 217*f0865ec9SKyle Evans nn_src_t n, e; 218*f0865ec9SKyle Evans 219*f0865ec9SKyle Evans /* Sanity checks */ 220*f0865ec9SKyle Evans MUST_HAVE((pub != NULL), ret, err); 221*f0865ec9SKyle Evans 222*f0865ec9SKyle Evans /* Make things more readable */ 223*f0865ec9SKyle Evans n = &(pub->n); 224*f0865ec9SKyle Evans e = &(pub->e); 225*f0865ec9SKyle Evans 226*f0865ec9SKyle Evans /* Sanity checks */ 227*f0865ec9SKyle Evans ret = nn_check_initialized(n); EG(ret, err); 228*f0865ec9SKyle Evans ret = nn_check_initialized(e); EG(ret, err); 229*f0865ec9SKyle Evans 230*f0865ec9SKyle Evans /* Check that m is indeed in [0, n-1], trigger an error if not */ 231*f0865ec9SKyle Evans MUST_HAVE((!nn_cmp(m, n, &cmp)) && (cmp < 0), ret, err); 232*f0865ec9SKyle Evans 233*f0865ec9SKyle Evans /* Compute c = m^e mod n 234*f0865ec9SKyle Evans * NOTE: we use our internal *insecure* modular exponentation as we 235*f0865ec9SKyle Evans * are handling public key and data. 236*f0865ec9SKyle Evans */ 237*f0865ec9SKyle Evans ret = _nn_mod_pow_insecure(c, m, e, n); 238*f0865ec9SKyle Evans 239*f0865ec9SKyle Evans err: 240*f0865ec9SKyle Evans PTR_NULLIFY(n); 241*f0865ec9SKyle Evans PTR_NULLIFY(e); 242*f0865ec9SKyle Evans 243*f0865ec9SKyle Evans return ret; 244*f0865ec9SKyle Evans } 245*f0865ec9SKyle Evans 246*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 247*f0865ec9SKyle Evans #define RSA_EXPONENT_BLINDING_SIZE 128 248*f0865ec9SKyle Evans /* 249*f0865ec9SKyle Evans * Blind an exponent with a "small" multiple (of size "bits") of the input mod or (mod-1). 250*f0865ec9SKyle Evans * We use a relatively small multiple mainly because of potential big performance impacts on 251*f0865ec9SKyle Evans * modular exponentiation. 252*f0865ec9SKyle Evans */ 253*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsa_blind_exponent(nn_src_t e, nn_src_t mod, nn_t out, bitcnt_t bits, u8 dec) 254*f0865ec9SKyle Evans { 255*f0865ec9SKyle Evans int ret, check; 256*f0865ec9SKyle Evans nn b; 257*f0865ec9SKyle Evans b.magic = WORD(0); 258*f0865ec9SKyle Evans 259*f0865ec9SKyle Evans ret = nn_init(&b, 0); EG(ret, err); 260*f0865ec9SKyle Evans ret = nn_init(out, 0); EG(ret, err); 261*f0865ec9SKyle Evans 262*f0865ec9SKyle Evans ret = nn_one(out); EG(ret, err); 263*f0865ec9SKyle Evans ret = nn_lshift(out, out, bits); EG(ret, err); 264*f0865ec9SKyle Evans ret = nn_iszero(out, &check); EG(ret, err); 265*f0865ec9SKyle Evans /* Check for overflow */ 266*f0865ec9SKyle Evans MUST_HAVE(!check, ret, err); 267*f0865ec9SKyle Evans 268*f0865ec9SKyle Evans /* Get a random value of "bits" count */ 269*f0865ec9SKyle Evans ret = nn_get_random_mod(&b, out); EG(ret, err); 270*f0865ec9SKyle Evans 271*f0865ec9SKyle Evans if(dec){ 272*f0865ec9SKyle Evans ret = nn_copy(out, mod); EG(ret, err); 273*f0865ec9SKyle Evans ret = nn_dec(out, out); EG(ret, err); 274*f0865ec9SKyle Evans ret = nn_mul(&b, &b, out); EG(ret, err); 275*f0865ec9SKyle Evans } 276*f0865ec9SKyle Evans else{ 277*f0865ec9SKyle Evans ret = nn_mul(&b, &b, mod); EG(ret, err); 278*f0865ec9SKyle Evans } 279*f0865ec9SKyle Evans 280*f0865ec9SKyle Evans ret = nn_add(out, e, &b); 281*f0865ec9SKyle Evans 282*f0865ec9SKyle Evans err: 283*f0865ec9SKyle Evans nn_uninit(&b); 284*f0865ec9SKyle Evans 285*f0865ec9SKyle Evans return ret; 286*f0865ec9SKyle Evans } 287*f0865ec9SKyle Evans #endif 288*f0865ec9SKyle Evans 289*f0865ec9SKyle Evans /* The raw RSADP function as defined in RFC 8017 section 5.1.2 290*f0865ec9SKyle Evans * Input: an RSA private key 'priv' and a big int ciphertext 'c' 291*f0865ec9SKyle Evans * Output: a big int clear message 'm' 292*f0865ec9SKyle Evans * Assumption: RSA private key 'priv' is valid 293*f0865ec9SKyle Evans */ 294*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_crt_coeffs(const rsa_priv_key *priv, nn_src_t c, nn_t m, u8 u) 295*f0865ec9SKyle Evans { 296*f0865ec9SKyle Evans int ret; 297*f0865ec9SKyle Evans unsigned int i; 298*f0865ec9SKyle Evans nn_src_t r_i, d_i, t_i, r_i_1; 299*f0865ec9SKyle Evans nn m_i, h, R; 300*f0865ec9SKyle Evans m_i.magic = h.magic = R.magic = WORD(0); 301*f0865ec9SKyle Evans 302*f0865ec9SKyle Evans /* Sanity check on u */ 303*f0865ec9SKyle Evans MUST_HAVE((u < MAX_CRT_COEFFS), ret, err); 304*f0865ec9SKyle Evans 305*f0865ec9SKyle Evans ret = nn_init(&m_i, 0); EG(ret, err); 306*f0865ec9SKyle Evans ret = nn_init(&h, 0); EG(ret, err); 307*f0865ec9SKyle Evans ret = nn_init(&R, 0); EG(ret, err); 308*f0865ec9SKyle Evans /* NOTE: this is an internal function, sanity checks on priv and u have 309*f0865ec9SKyle Evans * been performed by the callers. 310*f0865ec9SKyle Evans */ 311*f0865ec9SKyle Evans /* R = r_1 */ 312*f0865ec9SKyle Evans ret = nn_copy(&R, &(priv->key.crt.coeffs[0].r)); EG(ret, err); 313*f0865ec9SKyle Evans /* Loop */ 314*f0865ec9SKyle Evans for(i = 1; i < u; i++){ 315*f0865ec9SKyle Evans r_i_1 = &(priv->key.crt.coeffs[i-1].r); 316*f0865ec9SKyle Evans r_i = &(priv->key.crt.coeffs[i].r); 317*f0865ec9SKyle Evans d_i = &(priv->key.crt.coeffs[i].d); 318*f0865ec9SKyle Evans t_i = &(priv->key.crt.coeffs[i].t); 319*f0865ec9SKyle Evans 320*f0865ec9SKyle Evans /* Sanity checks */ 321*f0865ec9SKyle Evans ret = nn_check_initialized(r_i_1); EG(ret, err); 322*f0865ec9SKyle Evans ret = nn_check_initialized(r_i); EG(ret, err); 323*f0865ec9SKyle Evans ret = nn_check_initialized(d_i); EG(ret, err); 324*f0865ec9SKyle Evans ret = nn_check_initialized(t_i); EG(ret, err); 325*f0865ec9SKyle Evans 326*f0865ec9SKyle Evans /* m_i = c^(d_i) mod r_i */ 327*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 328*f0865ec9SKyle Evans ret = _rsa_blind_exponent(d_i, r_i, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err); 329*f0865ec9SKyle Evans ret = nn_mod_pow(&m_i, c, &h, r_i); EG(ret, err); 330*f0865ec9SKyle Evans #else 331*f0865ec9SKyle Evans ret = nn_mod_pow(&m_i, c, d_i, r_i); EG(ret, err); 332*f0865ec9SKyle Evans #endif 333*f0865ec9SKyle Evans /* R = R * r_(i-1) */ 334*f0865ec9SKyle Evans ret = nn_mul(&R, &R, r_i_1); EG(ret, err); 335*f0865ec9SKyle Evans /* h = (m_i - m) * t_i mod r_i */ 336*f0865ec9SKyle Evans ret = nn_mod(&h, m, r_i); EG(ret, err); 337*f0865ec9SKyle Evans ret = nn_mod_sub(&h, &m_i, &h, r_i); EG(ret, err); 338*f0865ec9SKyle Evans ret = nn_mod_mul(&h, &h, t_i, r_i); EG(ret, err); 339*f0865ec9SKyle Evans /* m = m + R * h */ 340*f0865ec9SKyle Evans ret = nn_mul(&h, &R, &h); EG(ret, err); 341*f0865ec9SKyle Evans ret = nn_add(m, m, &h); EG(ret, err); 342*f0865ec9SKyle Evans } 343*f0865ec9SKyle Evans 344*f0865ec9SKyle Evans err: 345*f0865ec9SKyle Evans nn_uninit(&m_i); 346*f0865ec9SKyle Evans nn_uninit(&h); 347*f0865ec9SKyle Evans nn_uninit(&R); 348*f0865ec9SKyle Evans 349*f0865ec9SKyle Evans PTR_NULLIFY(r_i); 350*f0865ec9SKyle Evans PTR_NULLIFY(d_i); 351*f0865ec9SKyle Evans PTR_NULLIFY(t_i); 352*f0865ec9SKyle Evans PTR_NULLIFY(r_i_1); 353*f0865ec9SKyle Evans 354*f0865ec9SKyle Evans return ret; 355*f0865ec9SKyle Evans } 356*f0865ec9SKyle Evans 357*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_crt(const rsa_priv_key *priv, nn_src_t c, nn_t m) 358*f0865ec9SKyle Evans { 359*f0865ec9SKyle Evans int ret; 360*f0865ec9SKyle Evans nn_src_t p, q, dP, dQ, qInv; 361*f0865ec9SKyle Evans nn m_1, m_2, h, msb_fixed; 362*f0865ec9SKyle Evans u8 u; 363*f0865ec9SKyle Evans m_1.magic = m_2.magic = h.magic = WORD(0); 364*f0865ec9SKyle Evans 365*f0865ec9SKyle Evans ret = nn_init(&m_1, 0); EG(ret, err); 366*f0865ec9SKyle Evans ret = nn_init(&m_2, 0); EG(ret, err); 367*f0865ec9SKyle Evans ret = nn_init(&h, 0); EG(ret, err); 368*f0865ec9SKyle Evans ret = nn_init(&msb_fixed, 0); EG(ret, err); 369*f0865ec9SKyle Evans 370*f0865ec9SKyle Evans /* Make things more readable */ 371*f0865ec9SKyle Evans p = &(priv->key.crt.p); 372*f0865ec9SKyle Evans q = &(priv->key.crt.q); 373*f0865ec9SKyle Evans dP = &(priv->key.crt.dP); 374*f0865ec9SKyle Evans dQ = &(priv->key.crt.dQ); 375*f0865ec9SKyle Evans qInv = &(priv->key.crt.qInv); 376*f0865ec9SKyle Evans u = priv->key.crt.u; 377*f0865ec9SKyle Evans 378*f0865ec9SKyle Evans /* Sanity checks */ 379*f0865ec9SKyle Evans ret = nn_check_initialized(p); EG(ret, err); 380*f0865ec9SKyle Evans ret = nn_check_initialized(q); EG(ret, err); 381*f0865ec9SKyle Evans ret = nn_check_initialized(dP); EG(ret, err); 382*f0865ec9SKyle Evans ret = nn_check_initialized(dQ); EG(ret, err); 383*f0865ec9SKyle Evans ret = nn_check_initialized(qInv); EG(ret, err); 384*f0865ec9SKyle Evans 385*f0865ec9SKyle Evans /* m_1 = c^dP mod p */ 386*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 387*f0865ec9SKyle Evans ret = _rsa_blind_exponent(dP, p, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err); 388*f0865ec9SKyle Evans ret = nn_mod_pow(&m_1, c, &h, p); EG(ret, err); 389*f0865ec9SKyle Evans #else 390*f0865ec9SKyle Evans ret = nn_mod_pow(&m_1, c, dP, p); EG(ret, err); 391*f0865ec9SKyle Evans #endif 392*f0865ec9SKyle Evans /* m_2 = c^dQ mod q */ 393*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 394*f0865ec9SKyle Evans ret = _rsa_blind_exponent(dQ, q, &h, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 1); EG(ret, err); 395*f0865ec9SKyle Evans ret = nn_mod_pow(&m_2, c, &h, q); EG(ret, err); 396*f0865ec9SKyle Evans #else 397*f0865ec9SKyle Evans ret = nn_mod_pow(&m_2, c, dQ, q); EG(ret, err); 398*f0865ec9SKyle Evans #endif 399*f0865ec9SKyle Evans /* h = (m_1 - m_2) * qInv mod p */ 400*f0865ec9SKyle Evans ret = nn_mod(&h, &m_2, p); EG(ret, err); 401*f0865ec9SKyle Evans ret = nn_mod_sub(&h, &m_1, &h, p); EG(ret, err); 402*f0865ec9SKyle Evans ret = nn_mod_mul(&h, &h, qInv, p); EG(ret, err); 403*f0865ec9SKyle Evans /* m = m_2 + q * h */ 404*f0865ec9SKyle Evans ret = nn_mul(m, &h, q); EG(ret, err); 405*f0865ec9SKyle Evans ret = nn_add(m, &m_2, m); EG(ret, err); 406*f0865ec9SKyle Evans 407*f0865ec9SKyle Evans if(u > 1){ 408*f0865ec9SKyle Evans ret = rsadp_crt_coeffs(priv, c, m, u); 409*f0865ec9SKyle Evans } 410*f0865ec9SKyle Evans 411*f0865ec9SKyle Evans err: 412*f0865ec9SKyle Evans nn_uninit(&m_1); 413*f0865ec9SKyle Evans nn_uninit(&m_2); 414*f0865ec9SKyle Evans nn_uninit(&h); 415*f0865ec9SKyle Evans 416*f0865ec9SKyle Evans PTR_NULLIFY(p); 417*f0865ec9SKyle Evans PTR_NULLIFY(q); 418*f0865ec9SKyle Evans PTR_NULLIFY(dP); 419*f0865ec9SKyle Evans PTR_NULLIFY(dQ); 420*f0865ec9SKyle Evans PTR_NULLIFY(qInv); 421*f0865ec9SKyle Evans 422*f0865ec9SKyle Evans return ret; 423*f0865ec9SKyle Evans } 424*f0865ec9SKyle Evans 425*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsadp_nocrt(const rsa_priv_key *priv, nn_src_t c, nn_t m) 426*f0865ec9SKyle Evans { 427*f0865ec9SKyle Evans int ret, cmp; 428*f0865ec9SKyle Evans nn_src_t n, d, p, q; 429*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 430*f0865ec9SKyle Evans nn b1, b2; 431*f0865ec9SKyle Evans b1.magic = b2.magic = WORD(0); 432*f0865ec9SKyle Evans #endif 433*f0865ec9SKyle Evans /* Make things more readable */ 434*f0865ec9SKyle Evans if(priv->type == RSA_SIMPLE){ 435*f0865ec9SKyle Evans n = &(priv->key.s.n); 436*f0865ec9SKyle Evans d = &(priv->key.s.d); 437*f0865ec9SKyle Evans } 438*f0865ec9SKyle Evans else if(priv->type == RSA_SIMPLE_PQ){ 439*f0865ec9SKyle Evans n = &(priv->key.s_pq.n); 440*f0865ec9SKyle Evans d = &(priv->key.s_pq.d); 441*f0865ec9SKyle Evans } 442*f0865ec9SKyle Evans else{ 443*f0865ec9SKyle Evans ret = -1; 444*f0865ec9SKyle Evans goto err; 445*f0865ec9SKyle Evans } 446*f0865ec9SKyle Evans /* Sanity checks */ 447*f0865ec9SKyle Evans ret = nn_check_initialized(n); EG(ret, err); 448*f0865ec9SKyle Evans ret = nn_check_initialized(d); EG(ret, err); 449*f0865ec9SKyle Evans /* Check that c is indeed in [0, n-1], trigger an error if not */ 450*f0865ec9SKyle Evans MUST_HAVE((!nn_cmp(c, n, &cmp)) && (cmp < 0), ret, err); 451*f0865ec9SKyle Evans 452*f0865ec9SKyle Evans /* Compute m = c^d mod n */ 453*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 454*f0865ec9SKyle Evans /* When we are asked to use exponent blinding, we MUST have a RSA_SIMPLE_PQ 455*f0865ec9SKyle Evans * type key in order to be able to compute our Phi(n) = (p-1)(q-1) and perform 456*f0865ec9SKyle Evans * the blinding. 457*f0865ec9SKyle Evans */ 458*f0865ec9SKyle Evans if(priv->type == RSA_SIMPLE_PQ){ 459*f0865ec9SKyle Evans p = &(priv->key.s_pq.p); 460*f0865ec9SKyle Evans q = &(priv->key.s_pq.q); 461*f0865ec9SKyle Evans ret = nn_init(&b1, 0); EG(ret, err); 462*f0865ec9SKyle Evans ret = nn_init(&b2, 0); EG(ret, err); 463*f0865ec9SKyle Evans ret = nn_dec(&b1, p); EG(ret, err); 464*f0865ec9SKyle Evans ret = nn_dec(&b2, q); EG(ret, err); 465*f0865ec9SKyle Evans ret = nn_mul(&b1, &b1, &b2); EG(ret, err); 466*f0865ec9SKyle Evans ret = _rsa_blind_exponent(d, &b1, &b2, (bitcnt_t)RSA_EXPONENT_BLINDING_SIZE, 0); EG(ret, err); 467*f0865ec9SKyle Evans ret = nn_mod_pow(m, c, &b2, n); EG(ret, err); 468*f0865ec9SKyle Evans } 469*f0865ec9SKyle Evans else{ 470*f0865ec9SKyle Evans ret = -1; 471*f0865ec9SKyle Evans goto err; 472*f0865ec9SKyle Evans } 473*f0865ec9SKyle Evans #else 474*f0865ec9SKyle Evans FORCE_USED_VAR(p); 475*f0865ec9SKyle Evans FORCE_USED_VAR(q); 476*f0865ec9SKyle Evans ret = nn_mod_pow(m, c, d, n); 477*f0865ec9SKyle Evans #endif 478*f0865ec9SKyle Evans 479*f0865ec9SKyle Evans err: 480*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 481*f0865ec9SKyle Evans nn_uninit(&b1); 482*f0865ec9SKyle Evans nn_uninit(&b2); 483*f0865ec9SKyle Evans #endif 484*f0865ec9SKyle Evans PTR_NULLIFY(n); 485*f0865ec9SKyle Evans PTR_NULLIFY(d); 486*f0865ec9SKyle Evans PTR_NULLIFY(p); 487*f0865ec9SKyle Evans PTR_NULLIFY(q); 488*f0865ec9SKyle Evans 489*f0865ec9SKyle Evans return ret; 490*f0865ec9SKyle Evans } 491*f0865ec9SKyle Evans 492*f0865ec9SKyle Evans int rsadp(const rsa_priv_key *priv, nn_src_t c, nn_t m) 493*f0865ec9SKyle Evans { 494*f0865ec9SKyle Evans int ret; 495*f0865ec9SKyle Evans 496*f0865ec9SKyle Evans /* Sanity checks */ 497*f0865ec9SKyle Evans MUST_HAVE((priv != NULL), ret, err); 498*f0865ec9SKyle Evans 499*f0865ec9SKyle Evans /* Do we have a simple or a CRT key? */ 500*f0865ec9SKyle Evans if((priv->type == RSA_SIMPLE) || (priv->type == RSA_SIMPLE_PQ)){ 501*f0865ec9SKyle Evans ret = rsadp_nocrt(priv, c, m); EG(ret, err); 502*f0865ec9SKyle Evans } 503*f0865ec9SKyle Evans else if(priv->type == RSA_CRT){ 504*f0865ec9SKyle Evans ret = rsadp_crt(priv, c, m); EG(ret, err); 505*f0865ec9SKyle Evans } 506*f0865ec9SKyle Evans else{ 507*f0865ec9SKyle Evans ret = -1; 508*f0865ec9SKyle Evans goto err; 509*f0865ec9SKyle Evans } 510*f0865ec9SKyle Evans 511*f0865ec9SKyle Evans err: 512*f0865ec9SKyle Evans return ret; 513*f0865ec9SKyle Evans } 514*f0865ec9SKyle Evans 515*f0865ec9SKyle Evans /* 516*f0865ec9SKyle Evans * The "hardened" version of rsadp that uses message blinding as well 517*f0865ec9SKyle Evans * as output check for Bellcore style fault attacks. 518*f0865ec9SKyle Evans * 519*f0865ec9SKyle Evans */ 520*f0865ec9SKyle Evans int rsadp_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, nn_src_t c, nn_t m) 521*f0865ec9SKyle Evans { 522*f0865ec9SKyle Evans int ret, check; 523*f0865ec9SKyle Evans nn_src_t n, e; 524*f0865ec9SKyle Evans nn b, binv; 525*f0865ec9SKyle Evans b.magic = binv.magic = WORD(0); 526*f0865ec9SKyle Evans 527*f0865ec9SKyle Evans /* Make things more readable */ 528*f0865ec9SKyle Evans n = &(pub->n); 529*f0865ec9SKyle Evans e = &(pub->e); 530*f0865ec9SKyle Evans 531*f0865ec9SKyle Evans /* Sanity checks */ 532*f0865ec9SKyle Evans MUST_HAVE((priv != NULL) && (pub != NULL), ret, err); 533*f0865ec9SKyle Evans 534*f0865ec9SKyle Evans /* Blind the message: get a random value for b prime with n 535*f0865ec9SKyle Evans * and compute its modular inverse. 536*f0865ec9SKyle Evans */ 537*f0865ec9SKyle Evans ret = nn_init(&b, 0); EG(ret, err); 538*f0865ec9SKyle Evans ret = nn_init(&binv, 0); EG(ret, err); 539*f0865ec9SKyle Evans ret = -1; 540*f0865ec9SKyle Evans while(ret){ 541*f0865ec9SKyle Evans ret = nn_get_random_mod(&b, n); EG(ret, err); 542*f0865ec9SKyle Evans ret = nn_modinv(&binv, &b, n); 543*f0865ec9SKyle Evans } 544*f0865ec9SKyle Evans /* Exponentiate the blinder to the public value */ 545*f0865ec9SKyle Evans ret = _nn_mod_pow_insecure(m, &b, e, n); EG(ret, err); 546*f0865ec9SKyle Evans /* Perform message blinding */ 547*f0865ec9SKyle Evans ret = nn_mod_mul(&b, m, c, n); EG(ret, err); 548*f0865ec9SKyle Evans 549*f0865ec9SKyle Evans /* Perform rsadp on the blinded message */ 550*f0865ec9SKyle Evans ret = rsadp(priv, &b, m); EG(ret, err); 551*f0865ec9SKyle Evans 552*f0865ec9SKyle Evans /* Unblind the result */ 553*f0865ec9SKyle Evans ret = nn_mod_mul(m, m, &binv, n); EG(ret, err); 554*f0865ec9SKyle Evans 555*f0865ec9SKyle Evans /* Now perform the public operation to check the result. 556*f0865ec9SKyle Evans * This is useful against some fault attacks (Bellcore style). 557*f0865ec9SKyle Evans */ 558*f0865ec9SKyle Evans ret = rsaep(pub, m, &b); EG(ret, err); 559*f0865ec9SKyle Evans ret = nn_cmp(c, &b, &check); EG(ret, err); 560*f0865ec9SKyle Evans MUST_HAVE((check == 0), ret, err); 561*f0865ec9SKyle Evans 562*f0865ec9SKyle Evans err: 563*f0865ec9SKyle Evans nn_uninit(&b); 564*f0865ec9SKyle Evans nn_uninit(&binv); 565*f0865ec9SKyle Evans 566*f0865ec9SKyle Evans PTR_NULLIFY(n); 567*f0865ec9SKyle Evans PTR_NULLIFY(e); 568*f0865ec9SKyle Evans 569*f0865ec9SKyle Evans return ret; 570*f0865ec9SKyle Evans } 571*f0865ec9SKyle Evans 572*f0865ec9SKyle Evans /* The raw RSASP1 function as defined in RFC 8017 section 5.2.1 573*f0865ec9SKyle Evans * Input: an RSA private key 'priv' and a big int message 'm' 574*f0865ec9SKyle Evans * Output: a big int signature 's' 575*f0865ec9SKyle Evans * Assumption: RSA private key 'priv' is valid 576*f0865ec9SKyle Evans */ 577*f0865ec9SKyle Evans int rsasp1(const rsa_priv_key *priv, nn_src_t m, nn_t s) 578*f0865ec9SKyle Evans { 579*f0865ec9SKyle Evans return rsadp(priv, m, s); 580*f0865ec9SKyle Evans } 581*f0865ec9SKyle Evans 582*f0865ec9SKyle Evans /* 583*f0865ec9SKyle Evans * The "hardened" version of rsasp1 that uses message blinding as well 584*f0865ec9SKyle Evans * as optional exponent blinding. 585*f0865ec9SKyle Evans * 586*f0865ec9SKyle Evans */ 587*f0865ec9SKyle Evans int rsasp1_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, nn_src_t m, nn_t s) 588*f0865ec9SKyle Evans { 589*f0865ec9SKyle Evans return rsadp_hardened(priv, pub, m, s); 590*f0865ec9SKyle Evans } 591*f0865ec9SKyle Evans 592*f0865ec9SKyle Evans 593*f0865ec9SKyle Evans /* The raw RSAVP1 function as defined in RFC 8017 section 5.2.2 594*f0865ec9SKyle Evans * Input: an RSA public key 'pub' and a big int signature 's' 595*f0865ec9SKyle Evans * Output: a big int ciphertext 'm' 596*f0865ec9SKyle Evans * Assumption: RSA public key 'pub' is valid 597*f0865ec9SKyle Evans */ 598*f0865ec9SKyle Evans int rsavp1(const rsa_pub_key *pub, nn_src_t s, nn_t m) 599*f0865ec9SKyle Evans { 600*f0865ec9SKyle Evans return rsaep(pub, s, m); 601*f0865ec9SKyle Evans } 602*f0865ec9SKyle Evans 603*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int rsa_digestinfo_from_hash(gen_hash_alg_type gen_hash_type, u8 *digestinfo, u32 *digestinfo_len) 604*f0865ec9SKyle Evans { 605*f0865ec9SKyle Evans int ret; 606*f0865ec9SKyle Evans 607*f0865ec9SKyle Evans /* Sanity check */ 608*f0865ec9SKyle Evans MUST_HAVE((digestinfo_len != NULL), ret, err); 609*f0865ec9SKyle Evans 610*f0865ec9SKyle Evans switch(gen_hash_type){ 611*f0865ec9SKyle Evans case HASH_MD2:{ 612*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 613*f0865ec9SKyle Evans 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, 614*f0865ec9SKyle Evans 0x05, 0x00, 0x04, 0x10 }; 615*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 616*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 617*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 618*f0865ec9SKyle Evans break; 619*f0865ec9SKyle Evans } 620*f0865ec9SKyle Evans case HASH_MD4:{ 621*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 622*f0865ec9SKyle Evans 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04, 623*f0865ec9SKyle Evans 0x05, 0x00, 0x04, 0x10 }; 624*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 625*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 626*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 627*f0865ec9SKyle Evans break; 628*f0865ec9SKyle Evans } 629*f0865ec9SKyle Evans case HASH_MD5:{ 630*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 631*f0865ec9SKyle Evans 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 632*f0865ec9SKyle Evans 0x05, 0x00, 0x04, 0x10 }; 633*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 634*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 635*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 636*f0865ec9SKyle Evans break; 637*f0865ec9SKyle Evans } 638*f0865ec9SKyle Evans case HASH_SHA0:{ 639*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 640*f0865ec9SKyle Evans 0x0e, 0x03, 0x02, 0x12, 0x05, 0x00, 0x04, 641*f0865ec9SKyle Evans 0x14 }; 642*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 643*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 644*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 645*f0865ec9SKyle Evans break; 646*f0865ec9SKyle Evans } 647*f0865ec9SKyle Evans case HASH_SHA1:{ 648*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 649*f0865ec9SKyle Evans 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 650*f0865ec9SKyle Evans 0x14 }; 651*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 652*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 653*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 654*f0865ec9SKyle Evans break; 655*f0865ec9SKyle Evans } 656*f0865ec9SKyle Evans case HASH_SHA224:{ 657*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 658*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 659*f0865ec9SKyle Evans 0x04, 0x05, 0x00, 0x04, 0x1c }; 660*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 661*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 662*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 663*f0865ec9SKyle Evans break; 664*f0865ec9SKyle Evans } 665*f0865ec9SKyle Evans case HASH_SHA256:{ 666*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 667*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 668*f0865ec9SKyle Evans 0x01, 0x05, 0x00, 0x04, 0x20 }; 669*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 670*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 671*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 672*f0865ec9SKyle Evans break; 673*f0865ec9SKyle Evans } 674*f0865ec9SKyle Evans case HASH_SHA384:{ 675*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 676*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 677*f0865ec9SKyle Evans 0x02, 0x05, 0x00, 0x04, 0x30 }; 678*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 679*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 680*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 681*f0865ec9SKyle Evans break; 682*f0865ec9SKyle Evans } 683*f0865ec9SKyle Evans case HASH_SHA512:{ 684*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 685*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 686*f0865ec9SKyle Evans 0x03, 0x05, 0x00, 0x04, 0x40 }; 687*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 688*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 689*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 690*f0865ec9SKyle Evans break; 691*f0865ec9SKyle Evans } 692*f0865ec9SKyle Evans case HASH_SHA512_224:{ 693*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 694*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 695*f0865ec9SKyle Evans 0x05, 0x05, 0x00, 0x04, 0x1c }; 696*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 697*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 698*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 699*f0865ec9SKyle Evans break; 700*f0865ec9SKyle Evans } 701*f0865ec9SKyle Evans case HASH_SHA512_256:{ 702*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 703*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 704*f0865ec9SKyle Evans 0x06, 0x05, 0x00, 0x04, 0x20 }; 705*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 706*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 707*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 708*f0865ec9SKyle Evans break; 709*f0865ec9SKyle Evans } 710*f0865ec9SKyle Evans case HASH_RIPEMD160:{ 711*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 712*f0865ec9SKyle Evans 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 713*f0865ec9SKyle Evans 0x14 }; 714*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 715*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 716*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 717*f0865ec9SKyle Evans break; 718*f0865ec9SKyle Evans } 719*f0865ec9SKyle Evans /* The following SHA-3 oids have been taken from 720*f0865ec9SKyle Evans * https://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt 721*f0865ec9SKyle Evans * 722*f0865ec9SKyle Evans * The specific case of SHA3-224 is infered from the OID of SHA3-224 although 723*f0865ec9SKyle Evans * not standardized. 724*f0865ec9SKyle Evans */ 725*f0865ec9SKyle Evans case HASH_SHA3_224:{ 726*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 727*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 728*f0865ec9SKyle Evans 0x07, 0x05, 0x00, 0x04, 0x1c }; 729*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 730*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 731*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 732*f0865ec9SKyle Evans break; 733*f0865ec9SKyle Evans } 734*f0865ec9SKyle Evans case HASH_SHA3_256:{ 735*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 736*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 737*f0865ec9SKyle Evans 0x08, 0x05, 0x00, 0x04, 0x20 }; 738*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 739*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 740*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 741*f0865ec9SKyle Evans break; 742*f0865ec9SKyle Evans } 743*f0865ec9SKyle Evans case HASH_SHA3_384:{ 744*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 745*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 746*f0865ec9SKyle Evans 0x09, 0x05, 0x00, 0x04, 0x30 }; 747*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 748*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 749*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 750*f0865ec9SKyle Evans break; 751*f0865ec9SKyle Evans } 752*f0865ec9SKyle Evans case HASH_SHA3_512:{ 753*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 754*f0865ec9SKyle Evans 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 755*f0865ec9SKyle Evans 0x0a ,0x05, 0x00, 0x04, 0x40 }; 756*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 757*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 758*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 759*f0865ec9SKyle Evans break; 760*f0865ec9SKyle Evans } 761*f0865ec9SKyle Evans /* For SM3, the "RSA Signing with SM3" OID is taken from: 762*f0865ec9SKyle Evans * http://gmssl.org/docs/oid.html 763*f0865ec9SKyle Evans */ 764*f0865ec9SKyle Evans case HASH_SM3:{ 765*f0865ec9SKyle Evans const u8 _digestinfo[] = { 0x30, 0x30, 0x30, 0x0d, 0x06, 0x08, 0x2A, 766*f0865ec9SKyle Evans 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x83, 0x78, 767*f0865ec9SKyle Evans 0x05, 0x00, 0x04, 0x20 }; 768*f0865ec9SKyle Evans MUST_HAVE(((*digestinfo_len) >= sizeof(_digestinfo)), ret, err); 769*f0865ec9SKyle Evans ret = local_memcpy(digestinfo, _digestinfo, sizeof(_digestinfo)); EG(ret, err); 770*f0865ec9SKyle Evans (*digestinfo_len) = sizeof(_digestinfo); 771*f0865ec9SKyle Evans break; 772*f0865ec9SKyle Evans } 773*f0865ec9SKyle Evans default:{ 774*f0865ec9SKyle Evans ret = -1; 775*f0865ec9SKyle Evans goto err; 776*f0865ec9SKyle Evans } 777*f0865ec9SKyle Evans } 778*f0865ec9SKyle Evans 779*f0865ec9SKyle Evans err: 780*f0865ec9SKyle Evans return ret; 781*f0865ec9SKyle Evans } 782*f0865ec9SKyle Evans 783*f0865ec9SKyle Evans /* GF1 as a mask generation function as described in RFC 8017 Appendix B.2.1 784*f0865ec9SKyle Evans * z is the 'seed', and zlen its length 785*f0865ec9SKyle Evans */ 786*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _mgf1(const u8 *z, u16 zlen, 787*f0865ec9SKyle Evans u8 *mask, u64 masklen, 788*f0865ec9SKyle Evans gen_hash_alg_type mgf_hash_type) 789*f0865ec9SKyle Evans { 790*f0865ec9SKyle Evans int ret; 791*f0865ec9SKyle Evans u8 hlen, block_size; 792*f0865ec9SKyle Evans u32 c, ceil; 793*f0865ec9SKyle Evans u8 C[4]; 794*f0865ec9SKyle Evans const u8 *input[3] = { z, C, NULL }; 795*f0865ec9SKyle Evans u32 ilens[3] = { zlen, 4, 0 }; 796*f0865ec9SKyle Evans u8 digest[MAX_DIGEST_SIZE]; 797*f0865ec9SKyle Evans 798*f0865ec9SKyle Evans /* Zeroize local variables */ 799*f0865ec9SKyle Evans ret = local_memset(C, 0, sizeof(C)); EG(ret, err); 800*f0865ec9SKyle Evans ret = local_memset(digest, 0, sizeof(digest)); EG(ret, err); 801*f0865ec9SKyle Evans 802*f0865ec9SKyle Evans /* Sanity checks */ 803*f0865ec9SKyle Evans MUST_HAVE((z != NULL) && (mask != NULL), ret, err); 804*f0865ec9SKyle Evans 805*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(mgf_hash_type, &hlen, &block_size); EG(ret, err); 806*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 807*f0865ec9SKyle Evans 808*f0865ec9SKyle Evans /* masklen must be < 2**32 * hlen */ 809*f0865ec9SKyle Evans MUST_HAVE((masklen < ((u64)hlen * ((u64)0x1 << 32))), ret, err); 810*f0865ec9SKyle Evans ceil = (u32)(masklen / hlen) + !!(masklen % hlen); 811*f0865ec9SKyle Evans 812*f0865ec9SKyle Evans for(c = 0; c < ceil; c++){ 813*f0865ec9SKyle Evans /* 3.A: C = I2OSP (counter, 4) */ 814*f0865ec9SKyle Evans C[0] = (u8)((c >> 24) & 0xff); 815*f0865ec9SKyle Evans C[1] = (u8)((c >> 16) & 0xff); 816*f0865ec9SKyle Evans C[2] = (u8)((c >> 8) & 0xff); 817*f0865ec9SKyle Evans C[3] = (u8)((c >> 0) & 0xff); 818*f0865ec9SKyle Evans 819*f0865ec9SKyle Evans /* 3.B + 4. */ 820*f0865ec9SKyle Evans if ((masklen % hlen) && (c == (ceil - 1))) { /* need last chunk smaller than hlen */ 821*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, digest, mgf_hash_type); EG(ret, err); 822*f0865ec9SKyle Evans ret = local_memcpy(&mask[c * hlen], digest, (u32)(masklen % hlen)); EG(ret, err); 823*f0865ec9SKyle Evans } else { /* common case, i.e. complete chunk */ 824*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, &mask[c * hlen], mgf_hash_type); EG(ret, err); 825*f0865ec9SKyle Evans } 826*f0865ec9SKyle Evans } 827*f0865ec9SKyle Evans err: 828*f0865ec9SKyle Evans return ret; 829*f0865ec9SKyle Evans } 830*f0865ec9SKyle Evans 831*f0865ec9SKyle Evans /* EMSA-PSS-ENCODE encoding as described in RFC 8017 section 9.1.1 832*f0865ec9SKyle Evans * NOTE: we enforce MGF1 as a mask generation function 833*f0865ec9SKyle Evans */ 834*f0865ec9SKyle Evans int emsa_pss_encode(const u8 *m, u32 mlen, u8 *em, u32 embits, 835*f0865ec9SKyle Evans u16 *eminlen, gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 836*f0865ec9SKyle Evans u32 saltlen, const u8 *forced_salt) 837*f0865ec9SKyle Evans { 838*f0865ec9SKyle Evans int ret; 839*f0865ec9SKyle Evans u8 hlen, block_size; 840*f0865ec9SKyle Evans u8 mhash[MAX_DIGEST_SIZE]; 841*f0865ec9SKyle Evans u8 h[MAX_DIGEST_SIZE]; 842*f0865ec9SKyle Evans u8 zeroes[8]; 843*f0865ec9SKyle Evans /* Reasonable sizes: 844*f0865ec9SKyle Evans * NOTE: for the cases where the salt exceeds this size, we return an error 845*f0865ec9SKyle Evans * alhough this should not happen if our underlying libecc supports the current 846*f0865ec9SKyle Evans * modulus size. 847*f0865ec9SKyle Evans */ 848*f0865ec9SKyle Evans u8 salt[NN_USABLE_MAX_BYTE_LEN]; 849*f0865ec9SKyle Evans u8 *dbmask = em; 850*f0865ec9SKyle Evans const u8 *input[2] = { m, NULL }; 851*f0865ec9SKyle Evans u32 ilens[2] = { mlen, 0 }; 852*f0865ec9SKyle Evans u32 emlen, dblen, pslen; 853*f0865ec9SKyle Evans unsigned int i; 854*f0865ec9SKyle Evans u8 mask; 855*f0865ec9SKyle Evans const u8 *input_[4] = { zeroes, mhash, salt, NULL }; 856*f0865ec9SKyle Evans u32 ilens_[4]; 857*f0865ec9SKyle Evans 858*f0865ec9SKyle Evans /* Zeroize local variables */ 859*f0865ec9SKyle Evans ret = local_memset(mhash, 0, sizeof(mhash)); EG(ret, err); 860*f0865ec9SKyle Evans ret = local_memset(h, 0, sizeof(h)); EG(ret, err); 861*f0865ec9SKyle Evans ret = local_memset(salt, 0, sizeof(salt)); EG(ret, err); 862*f0865ec9SKyle Evans ret = local_memset(zeroes, 0, sizeof(zeroes)); EG(ret, err); 863*f0865ec9SKyle Evans ret = local_memset(ilens_, 0, sizeof(ilens_)); EG(ret, err); 864*f0865ec9SKyle Evans 865*f0865ec9SKyle Evans /* Sanity checks */ 866*f0865ec9SKyle Evans MUST_HAVE((m != NULL) && (em != NULL) && (eminlen != NULL), ret, err); 867*f0865ec9SKyle Evans 868*f0865ec9SKyle Evans /* We only allow salt up to a certain size */ 869*f0865ec9SKyle Evans MUST_HAVE((saltlen <= sizeof(salt)), ret, err); 870*f0865ec9SKyle Evans emlen = BYTECEIL(embits); 871*f0865ec9SKyle Evans MUST_HAVE((emlen < (u32)((u32)0x1 << 16)), ret, err); 872*f0865ec9SKyle Evans 873*f0865ec9SKyle Evans /* Check that we have enough room for the output */ 874*f0865ec9SKyle Evans MUST_HAVE(((*eminlen) >= emlen), ret, err); 875*f0865ec9SKyle Evans 876*f0865ec9SKyle Evans /* Get the used hash information */ 877*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 878*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 879*f0865ec9SKyle Evans 880*f0865ec9SKyle Evans /* emBits at least 8hLen + 8sLen + 9 */ 881*f0865ec9SKyle Evans MUST_HAVE((embits >= ((8*(u32)hlen) + (8*(u32)saltlen) + 9)), ret, err); 882*f0865ec9SKyle Evans 883*f0865ec9SKyle Evans /* If emLen < hLen + sLen + 2, output "encoding error" and stop. */ 884*f0865ec9SKyle Evans MUST_HAVE((emlen >= ((u32)hlen + (u32)saltlen + 2)), ret, err); 885*f0865ec9SKyle Evans 886*f0865ec9SKyle Evans /* mHash = Hash(M) */ 887*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, mhash, gen_hash_type); EG(ret, err); 888*f0865ec9SKyle Evans 889*f0865ec9SKyle Evans /* Generate a random octet string salt of length sLen; if sLen = 0 890*f0865ec9SKyle Evans * then salt is the empty string. 891*f0865ec9SKyle Evans * M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; 892*f0865ec9SKyle Evans * H = Hash(M'), 893*f0865ec9SKyle Evans */ 894*f0865ec9SKyle Evans if(forced_salt != NULL){ 895*f0865ec9SKyle Evans /* We are given a forced salt, use it */ 896*f0865ec9SKyle Evans ret = local_memcpy(salt, forced_salt, saltlen); EG(ret, err); 897*f0865ec9SKyle Evans } 898*f0865ec9SKyle Evans else{ 899*f0865ec9SKyle Evans /* We only support generating salts of size <= 2**16 */ 900*f0865ec9SKyle Evans MUST_HAVE((saltlen <= 0xffff), ret, err); 901*f0865ec9SKyle Evans /* Get random salt */ 902*f0865ec9SKyle Evans ret = get_random(salt, (u16)saltlen); EG(ret, err); 903*f0865ec9SKyle Evans } 904*f0865ec9SKyle Evans ilens_[0] = sizeof(zeroes); 905*f0865ec9SKyle Evans ilens_[1] = hlen; 906*f0865ec9SKyle Evans ilens_[2] = saltlen; 907*f0865ec9SKyle Evans ilens_[3] = 0; 908*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input_, ilens_, h, gen_hash_type); EG(ret, err); 909*f0865ec9SKyle Evans 910*f0865ec9SKyle Evans /* dbMask = MGF(H, emLen - hLen - 1) 911*f0865ec9SKyle Evans * NOTE: dbmask points to &em[0] 912*f0865ec9SKyle Evans */ 913*f0865ec9SKyle Evans dblen = (emlen - hlen - 1); 914*f0865ec9SKyle Evans pslen = (dblen - saltlen - 1); /* padding string PS len */ 915*f0865ec9SKyle Evans ret = _mgf1(h, hlen, dbmask, dblen, mgf_hash_type); EG(ret, err); 916*f0865ec9SKyle Evans 917*f0865ec9SKyle Evans /* 918*f0865ec9SKyle Evans * maskedb = (PS || 0x01 || salt) xor dbmask. We compute maskeddb directly 919*f0865ec9SKyle Evans * in dbmask. 920*f0865ec9SKyle Evans */ 921*f0865ec9SKyle Evans 922*f0865ec9SKyle Evans /* 1) PS is made of 0 so xoring it with first pslen bytes of dbmask is a NOP */ 923*f0865ec9SKyle Evans 924*f0865ec9SKyle Evans /* 925*f0865ec9SKyle Evans * 2) the byte after padding string is 0x01. Do the xor with the associated 926*f0865ec9SKyle Evans * byte in dbmask 927*f0865ec9SKyle Evans */ 928*f0865ec9SKyle Evans dbmask[pslen] ^= 0x01; 929*f0865ec9SKyle Evans 930*f0865ec9SKyle Evans /* 3) xor the salt with the end of dbmask */ 931*f0865ec9SKyle Evans for (i = 0; i < saltlen; i++){ 932*f0865ec9SKyle Evans dbmask[dblen - saltlen + i] ^= salt[i]; 933*f0865ec9SKyle Evans } 934*f0865ec9SKyle Evans 935*f0865ec9SKyle Evans /* Set the leftmost 8emLen - emBits bits of the leftmost octet 936*f0865ec9SKyle Evans * in maskedDB to zero. 937*f0865ec9SKyle Evans */ 938*f0865ec9SKyle Evans mask = 0; 939*f0865ec9SKyle Evans for(i = 0; i < (8 - ((8*emlen) - embits)); i++){ 940*f0865ec9SKyle Evans mask = (u8)(mask | (0x1 << i)); 941*f0865ec9SKyle Evans } 942*f0865ec9SKyle Evans dbmask[0] &= mask; 943*f0865ec9SKyle Evans /* EM = maskedDB || H || 0xbc */ 944*f0865ec9SKyle Evans ret = local_memcpy(&em[dblen], h, hlen); EG(ret, err); 945*f0865ec9SKyle Evans em[emlen - 1] = 0xbc; 946*f0865ec9SKyle Evans (*eminlen) = (u16)emlen; 947*f0865ec9SKyle Evans 948*f0865ec9SKyle Evans err: 949*f0865ec9SKyle Evans return ret; 950*f0865ec9SKyle Evans } 951*f0865ec9SKyle Evans 952*f0865ec9SKyle Evans /* EMSA-PSS-VERIFY verification as described in RFC 8017 section 9.1.2 953*f0865ec9SKyle Evans * NOTE: we enforce MGF1 as a mask generation function 954*f0865ec9SKyle Evans */ 955*f0865ec9SKyle Evans int emsa_pss_verify(const u8 *m, u32 mlen, const u8 *em, 956*f0865ec9SKyle Evans u32 embits, u16 emlen, 957*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 958*f0865ec9SKyle Evans u32 saltlen) 959*f0865ec9SKyle Evans { 960*f0865ec9SKyle Evans int ret, cmp; 961*f0865ec9SKyle Evans u8 hlen, block_size; 962*f0865ec9SKyle Evans u8 mhash[MAX_DIGEST_SIZE]; 963*f0865ec9SKyle Evans u8 h_[MAX_DIGEST_SIZE]; 964*f0865ec9SKyle Evans u8 zeroes[8]; 965*f0865ec9SKyle Evans const u8 *input[2] = { m, NULL }; 966*f0865ec9SKyle Evans u32 ilens[2] = { mlen, 0 }; 967*f0865ec9SKyle Evans unsigned int i; 968*f0865ec9SKyle Evans u8 mask; 969*f0865ec9SKyle Evans u16 _emlen; 970*f0865ec9SKyle Evans /* 971*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 972*f0865ec9SKyle Evans */ 973*f0865ec9SKyle Evans u8 dbmask[NN_USABLE_MAX_BYTE_LEN]; 974*f0865ec9SKyle Evans u8 *db; 975*f0865ec9SKyle Evans const u8 *h, *salt, *maskeddb = em; 976*f0865ec9SKyle Evans u32 dblen; 977*f0865ec9SKyle Evans const u8 *input_[4]; 978*f0865ec9SKyle Evans u32 ilens_[4]; 979*f0865ec9SKyle Evans 980*f0865ec9SKyle Evans /* Zeroize local variables */ 981*f0865ec9SKyle Evans ret = local_memset(mhash, 0, sizeof(mhash)); EG(ret, err); 982*f0865ec9SKyle Evans ret = local_memset(h_, 0, sizeof(h_)); EG(ret, err); 983*f0865ec9SKyle Evans ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err); 984*f0865ec9SKyle Evans ret = local_memset(zeroes, 0, sizeof(zeroes)); EG(ret, err); 985*f0865ec9SKyle Evans ret = local_memset(input_, 0, sizeof(input_)); EG(ret, err); 986*f0865ec9SKyle Evans ret = local_memset(ilens_, 0, sizeof(ilens_)); EG(ret, err); 987*f0865ec9SKyle Evans 988*f0865ec9SKyle Evans /* Sanity checks */ 989*f0865ec9SKyle Evans MUST_HAVE((m != NULL) && (em != NULL), ret, err); 990*f0865ec9SKyle Evans 991*f0865ec9SKyle Evans /* Get the used hash information */ 992*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 993*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 994*f0865ec9SKyle Evans 995*f0865ec9SKyle Evans /* Let mHash = Hash(M), an octet string of length hLen */ 996*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, mhash, gen_hash_type); EG(ret, err); 997*f0865ec9SKyle Evans 998*f0865ec9SKyle Evans /* emBits at least 8hLen + 8sLen + 9 */ 999*f0865ec9SKyle Evans MUST_HAVE((embits >= ((8*(u32)hlen) + (8*(u32)saltlen) + 9)), ret, err); 1000*f0865ec9SKyle Evans 1001*f0865ec9SKyle Evans /* Check that emLen == \ceil(emBits/8) */ 1002*f0865ec9SKyle Evans MUST_HAVE((((embits / 8) + 1) < (u32)((u32)0x1 << 16)), ret, err); 1003*f0865ec9SKyle Evans _emlen = ((embits % 8) == 0) ? (u16)(embits / 8) : (u16)((embits / 8) + 1); 1004*f0865ec9SKyle Evans MUST_HAVE((_emlen == emlen), ret, err); 1005*f0865ec9SKyle Evans 1006*f0865ec9SKyle Evans /* If emLen < hLen + sLen + 2, output "inconsistent" and stop */ 1007*f0865ec9SKyle Evans MUST_HAVE((emlen >= ((u32)hlen + (u32)saltlen + 2)), ret, err); 1008*f0865ec9SKyle Evans 1009*f0865ec9SKyle Evans /* If the rightmost octet of EM does not have hexadecimal value 0xbc, output "inconsistent" and stop */ 1010*f0865ec9SKyle Evans MUST_HAVE((em[emlen - 1] == 0xbc), ret, err); 1011*f0865ec9SKyle Evans 1012*f0865ec9SKyle Evans /* If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are not all equal to zero, 1013*f0865ec9SKyle Evans * output "inconsistent" and stop 1014*f0865ec9SKyle Evans * NOTE: maskeddb points to &em[0] 1015*f0865ec9SKyle Evans */ 1016*f0865ec9SKyle Evans mask = 0; 1017*f0865ec9SKyle Evans for(i = 0; i < (8 - ((unsigned int)(8*emlen) - embits)); i++){ 1018*f0865ec9SKyle Evans mask = (u8)(mask | (0x1 << i)); 1019*f0865ec9SKyle Evans } 1020*f0865ec9SKyle Evans MUST_HAVE(((maskeddb[0] & (~mask)) == 0), ret, err); 1021*f0865ec9SKyle Evans 1022*f0865ec9SKyle Evans /* dbMask = MGF(H, emLen - hLen - 1) */ 1023*f0865ec9SKyle Evans dblen = (u32)(emlen - hlen - 1); 1024*f0865ec9SKyle Evans h = &em[dblen]; 1025*f0865ec9SKyle Evans MUST_HAVE(((u16)dblen <= sizeof(dbmask)), ret, err); /* sanity check for overflow */ 1026*f0865ec9SKyle Evans ret = _mgf1(h, hlen, dbmask, dblen, mgf_hash_type); EG(ret, err); 1027*f0865ec9SKyle Evans /* DB = maskedDB \xor dbMask */ 1028*f0865ec9SKyle Evans db = &dbmask[0]; 1029*f0865ec9SKyle Evans for(i = 0; i < (u16)dblen; i++){ 1030*f0865ec9SKyle Evans db[i] = (dbmask[i] ^ maskeddb[i]); 1031*f0865ec9SKyle Evans } 1032*f0865ec9SKyle Evans /* Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero */ 1033*f0865ec9SKyle Evans db[0] &= mask; 1034*f0865ec9SKyle Evans 1035*f0865ec9SKyle Evans /* 1036*f0865ec9SKyle Evans * If the emLen - hLen - sLen - 2 leftmost octets of DB are not 1037*f0865ec9SKyle Evans * zero or if the octet at position emLen - hLen - sLen - 1 (the 1038*f0865ec9SKyle Evans * leftmost position is "position 1") does not have hexadecimal 1039*f0865ec9SKyle Evans * value 0x01, output "inconsistent" and stop. 1040*f0865ec9SKyle Evans */ 1041*f0865ec9SKyle Evans for(i = 0; i < (u16)(dblen - saltlen - 1); i++){ 1042*f0865ec9SKyle Evans MUST_HAVE((db[i] == 0x00), ret, err); 1043*f0865ec9SKyle Evans } 1044*f0865ec9SKyle Evans MUST_HAVE((db[dblen - saltlen - 1] == 0x01), ret, err); 1045*f0865ec9SKyle Evans 1046*f0865ec9SKyle Evans /* Let salt be the last sLen octets of DB */ 1047*f0865ec9SKyle Evans salt = &db[dblen - saltlen]; 1048*f0865ec9SKyle Evans /* 1049*f0865ec9SKyle Evans * Let H' = Hash(M'), an octet string of length hLen with 1050*f0865ec9SKyle Evans * M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt 1051*f0865ec9SKyle Evans */ 1052*f0865ec9SKyle Evans /* Fill input_ */ 1053*f0865ec9SKyle Evans input_[0] = zeroes; 1054*f0865ec9SKyle Evans input_[1] = mhash; 1055*f0865ec9SKyle Evans input_[2] = salt; 1056*f0865ec9SKyle Evans input_[3] = NULL; 1057*f0865ec9SKyle Evans /* Fill ilens_ */ 1058*f0865ec9SKyle Evans ilens_[0] = sizeof(zeroes); 1059*f0865ec9SKyle Evans ilens_[1] = hlen; 1060*f0865ec9SKyle Evans ilens_[2] = saltlen; 1061*f0865ec9SKyle Evans ilens_[3] = 0; 1062*f0865ec9SKyle Evans /* Hash */ 1063*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input_, ilens_, h_, gen_hash_type); EG(ret, err); 1064*f0865ec9SKyle Evans 1065*f0865ec9SKyle Evans /* If H = H', output "consistent". Otherwise, output "inconsistent" */ 1066*f0865ec9SKyle Evans ret = are_equal(h, h_, hlen, &cmp); EG(ret, err); 1067*f0865ec9SKyle Evans if(!cmp){ 1068*f0865ec9SKyle Evans ret = -1; 1069*f0865ec9SKyle Evans } 1070*f0865ec9SKyle Evans 1071*f0865ec9SKyle Evans err: 1072*f0865ec9SKyle Evans return ret; 1073*f0865ec9SKyle Evans } 1074*f0865ec9SKyle Evans 1075*f0865ec9SKyle Evans /* EMSA-PKCS1-v1_5 encoding as described in RFC 8017 section 9.2 1076*f0865ec9SKyle Evans */ 1077*f0865ec9SKyle Evans int emsa_pkcs1_v1_5_encode(const u8 *m, u32 mlen, u8 *em, u16 emlen, 1078*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type) 1079*f0865ec9SKyle Evans { 1080*f0865ec9SKyle Evans int ret; 1081*f0865ec9SKyle Evans const u8 *input[2] = { m, NULL }; 1082*f0865ec9SKyle Evans u32 ilens[2] = { mlen, 0 }; 1083*f0865ec9SKyle Evans u8 digest_size, block_size; 1084*f0865ec9SKyle Evans u8 digest[MAX_DIGEST_SIZE]; 1085*f0865ec9SKyle Evans u32 digestinfo_len = 0; 1086*f0865ec9SKyle Evans u32 tlen = 0; 1087*f0865ec9SKyle Evans 1088*f0865ec9SKyle Evans /* Zeroize local variables */ 1089*f0865ec9SKyle Evans ret = local_memset(digest, 0, sizeof(digest)); EG(ret, err); 1090*f0865ec9SKyle Evans 1091*f0865ec9SKyle Evans /* Compute H = Hash(M) */ 1092*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &digest_size, &block_size); EG(ret, err); 1093*f0865ec9SKyle Evans MUST_HAVE((digest_size <= MAX_DIGEST_SIZE), ret, err); 1094*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, digest, gen_hash_type); EG(ret, err); 1095*f0865ec9SKyle Evans 1096*f0865ec9SKyle Evans /* Now encode: 1097*f0865ec9SKyle Evans * 1098*f0865ec9SKyle Evans * DigestInfo ::= SEQUENCE { 1099*f0865ec9SKyle Evans * digestAlgorithm AlgorithmIdentifier, 1100*f0865ec9SKyle Evans * digest OCTET STRING 1101*f0865ec9SKyle Evans * } 1102*f0865ec9SKyle Evans */ 1103*f0865ec9SKyle Evans digestinfo_len = emlen; 1104*f0865ec9SKyle Evans /* NOTE: the rsa_digestinfo_from_hash returns the size of DigestInfo *WITHOUT* the 1105*f0865ec9SKyle Evans * appended raw hash, tlen is the real size of the complete encoded DigestInfo. 1106*f0865ec9SKyle Evans */ 1107*f0865ec9SKyle Evans ret = rsa_digestinfo_from_hash(gen_hash_type, em, &digestinfo_len); EG(ret, err); 1108*f0865ec9SKyle Evans tlen = (digestinfo_len + digest_size); 1109*f0865ec9SKyle Evans 1110*f0865ec9SKyle Evans /* If emLen < tLen + 11, output "intended encoded message length too short" and stop */ 1111*f0865ec9SKyle Evans MUST_HAVE((emlen >= (tlen + 11)), ret, err); 1112*f0865ec9SKyle Evans 1113*f0865ec9SKyle Evans /* Copy T at the end of em */ 1114*f0865ec9SKyle Evans digestinfo_len = emlen; 1115*f0865ec9SKyle Evans ret = rsa_digestinfo_from_hash(gen_hash_type, &em[emlen - tlen], &digestinfo_len); EG(ret, err); 1116*f0865ec9SKyle Evans ret = local_memcpy(&em[emlen - tlen + digestinfo_len], digest, digest_size); EG(ret, err); 1117*f0865ec9SKyle Evans 1118*f0865ec9SKyle Evans /* 1119*f0865ec9SKyle Evans * Format 0x00 || 0x01 || PS || 0x00 before 1120*f0865ec9SKyle Evans */ 1121*f0865ec9SKyle Evans em[0] = 0x00; 1122*f0865ec9SKyle Evans em[1] = 0x01; 1123*f0865ec9SKyle Evans em[emlen - tlen - 1] = 0x00; 1124*f0865ec9SKyle Evans ret = local_memset(&em[2], 0xff, emlen - tlen - 3); 1125*f0865ec9SKyle Evans 1126*f0865ec9SKyle Evans err: 1127*f0865ec9SKyle Evans return ret; 1128*f0865ec9SKyle Evans } 1129*f0865ec9SKyle Evans 1130*f0865ec9SKyle Evans /****************************************************************/ 1131*f0865ec9SKyle Evans /******** Encryption schemes *************************************/ 1132*f0865ec9SKyle Evans /* The RSAES-PKCS1-V1_5-ENCRYPT algorithm as described in RFC 8017 section 7.2.1 1133*f0865ec9SKyle Evans * 1134*f0865ec9SKyle Evans */ 1135*f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_encrypt(const rsa_pub_key *pub, const u8 *m, u32 mlen, 1136*f0865ec9SKyle Evans u8 *c, u32 *clen, u32 modbits, 1137*f0865ec9SKyle Evans const u8 *forced_seed, u32 seedlen) 1138*f0865ec9SKyle Evans { 1139*f0865ec9SKyle Evans int ret; 1140*f0865ec9SKyle Evans u32 k; 1141*f0865ec9SKyle Evans u8 *em = c; 1142*f0865ec9SKyle Evans unsigned int i; 1143*f0865ec9SKyle Evans nn m_, c_; 1144*f0865ec9SKyle Evans m_.magic = c_.magic = WORD(0); 1145*f0865ec9SKyle Evans 1146*f0865ec9SKyle Evans MUST_HAVE((clen != NULL) && (c != NULL) && (m != NULL), ret, err); 1147*f0865ec9SKyle Evans 1148*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1149*f0865ec9SKyle Evans 1150*f0865ec9SKyle Evans /* Check on lengths */ 1151*f0865ec9SKyle Evans MUST_HAVE((k >= 11), ret, err); 1152*f0865ec9SKyle Evans MUST_HAVE((mlen <= (k - 11)), ret, err); 1153*f0865ec9SKyle Evans MUST_HAVE(((*clen) >= k), ret, err); 1154*f0865ec9SKyle Evans 1155*f0865ec9SKyle Evans /* EME-PKCS1-v1_5 encoding EM = 0x00 || 0x02 || PS || 0x00 || M */ 1156*f0865ec9SKyle Evans em[0] = 0x00; 1157*f0865ec9SKyle Evans em[1] = 0x02; 1158*f0865ec9SKyle Evans if(forced_seed == NULL){ 1159*f0865ec9SKyle Evans for(i = 0; i < (k - mlen - 3); i++){ 1160*f0865ec9SKyle Evans u8 rand_byte = 0; 1161*f0865ec9SKyle Evans while (!rand_byte) { 1162*f0865ec9SKyle Evans ret = get_random(&rand_byte, 1); EG(ret, err); 1163*f0865ec9SKyle Evans } 1164*f0865ec9SKyle Evans em[2 + i] = rand_byte; 1165*f0865ec9SKyle Evans } 1166*f0865ec9SKyle Evans } 1167*f0865ec9SKyle Evans else{ 1168*f0865ec9SKyle Evans MUST_HAVE((seedlen == (k - mlen - 3)), ret, err); 1169*f0865ec9SKyle Evans /* Check that the forced seed does not contain 0x00 */ 1170*f0865ec9SKyle Evans for(i = 0; i < seedlen; i++){ 1171*f0865ec9SKyle Evans MUST_HAVE((forced_seed[i] != 0), ret, err); 1172*f0865ec9SKyle Evans } 1173*f0865ec9SKyle Evans ret = local_memcpy(&em[2], forced_seed, seedlen); EG(ret, err); 1174*f0865ec9SKyle Evans } 1175*f0865ec9SKyle Evans em[k - mlen - 1] = 0x00; 1176*f0865ec9SKyle Evans ret = local_memcpy(&em[k - mlen], m, mlen); EG(ret, err); 1177*f0865ec9SKyle Evans 1178*f0865ec9SKyle Evans /* RSA encryption */ 1179*f0865ec9SKyle Evans /* m = OS2IP (EM) */ 1180*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1181*f0865ec9SKyle Evans ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err); 1182*f0865ec9SKyle Evans /* c = RSAEP ((n, e), m) */ 1183*f0865ec9SKyle Evans ret = rsaep(pub, &m_, &c_); EG(ret, err); 1184*f0865ec9SKyle Evans /* C = I2OSP (c, k) */ 1185*f0865ec9SKyle Evans ret = rsa_i2osp(&c_, c, (u16)k); EG(ret, err); 1186*f0865ec9SKyle Evans (*clen) = (u16)k; 1187*f0865ec9SKyle Evans 1188*f0865ec9SKyle Evans err: 1189*f0865ec9SKyle Evans nn_uninit(&m_); 1190*f0865ec9SKyle Evans nn_uninit(&c_); 1191*f0865ec9SKyle Evans /* Zeroify in case of error */ 1192*f0865ec9SKyle Evans if(ret && (clen != NULL)){ 1193*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(c, 0, (*clen))); 1194*f0865ec9SKyle Evans } 1195*f0865ec9SKyle Evans 1196*f0865ec9SKyle Evans return ret; 1197*f0865ec9SKyle Evans } 1198*f0865ec9SKyle Evans 1199*f0865ec9SKyle Evans /* The RSAES-PKCS1-V1_5-DECRYPT algorithm as described in RFC 8017 section 7.2.2 1200*f0865ec9SKyle Evans * 1201*f0865ec9SKyle Evans */ 1202*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen, 1203*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits) 1204*f0865ec9SKyle Evans { 1205*f0865ec9SKyle Evans int ret; 1206*f0865ec9SKyle Evans unsigned int i, pos; 1207*f0865ec9SKyle Evans u32 k; 1208*f0865ec9SKyle Evans u8 r; 1209*f0865ec9SKyle Evans u8 *em = m; 1210*f0865ec9SKyle Evans nn m_, c_; 1211*f0865ec9SKyle Evans m_.magic = c_.magic = WORD(0); 1212*f0865ec9SKyle Evans 1213*f0865ec9SKyle Evans MUST_HAVE((mlen != NULL) && (c != NULL) && (m != NULL), ret, err); 1214*f0865ec9SKyle Evans 1215*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1216*f0865ec9SKyle Evans 1217*f0865ec9SKyle Evans /* Check on lengths */ 1218*f0865ec9SKyle Evans MUST_HAVE((clen == k) && (k >= 11), ret, err); 1219*f0865ec9SKyle Evans MUST_HAVE(((*mlen) >= k), ret, err); 1220*f0865ec9SKyle Evans 1221*f0865ec9SKyle Evans /* RSA decryption */ 1222*f0865ec9SKyle Evans /* c = OS2IP (C) */ 1223*f0865ec9SKyle Evans ret = rsa_os2ip(&c_, c, clen); EG(ret, err); 1224*f0865ec9SKyle Evans /* m = RSADP ((n, d), c) */ 1225*f0865ec9SKyle Evans if(pub != NULL){ 1226*f0865ec9SKyle Evans ret = rsadp_hardened(priv, pub, &c_, &m_); EG(ret, err); 1227*f0865ec9SKyle Evans } 1228*f0865ec9SKyle Evans else{ 1229*f0865ec9SKyle Evans ret = rsadp(priv, &c_, &m_); EG(ret, err); 1230*f0865ec9SKyle Evans } 1231*f0865ec9SKyle Evans /* EM = I2OSP (m, k) */ 1232*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1233*f0865ec9SKyle Evans ret = rsa_i2osp(&m_, em, (u16)k); EG(ret, err); 1234*f0865ec9SKyle Evans 1235*f0865ec9SKyle Evans /* EME-PKCS1-v1_5 decoding: EM = 0x00 || 0x02 || PS || 0x00 || M */ 1236*f0865ec9SKyle Evans /* NOTE: we try our best to do the following in constant time to 1237*f0865ec9SKyle Evans * limit padding oracles here (see Bleichenbacher attacks). 1238*f0865ec9SKyle Evans */ 1239*f0865ec9SKyle Evans ret = (1 - (!!(em[0] == 0x00) & !!(em[1] == 0x02))); 1240*f0865ec9SKyle Evans pos = 0; 1241*f0865ec9SKyle Evans /* Handle the first zero octet after PS in constant time */ 1242*f0865ec9SKyle Evans for(i = 2; i < k; i++){ 1243*f0865ec9SKyle Evans unsigned int mask = !!(em[i] == 0x00) & !!(pos == 0); 1244*f0865ec9SKyle Evans pos = (mask * i) + ((1 - mask) * pos); 1245*f0865ec9SKyle Evans } 1246*f0865ec9SKyle Evans ret |= !(pos >= (2 + 8)); /* PS length is at least 8 (also implying we found a 0x00) */ 1247*f0865ec9SKyle Evans pos = (pos == 0) ? pos : (pos + 1); 1248*f0865ec9SKyle Evans /* We get a random value between 2 and k if we have an error so that 1249*f0865ec9SKyle Evans * we put a random value in pos. 1250*f0865ec9SKyle Evans */ 1251*f0865ec9SKyle Evans ret |= get_random((u8*)&i, 4); 1252*f0865ec9SKyle Evans /* Get a random value r for later loop dummy operations */ 1253*f0865ec9SKyle Evans ret |= get_random(&r, 1); 1254*f0865ec9SKyle Evans /* Update pos with random value in case of error to progress 1255*f0865ec9SKyle Evans * nominally with the algorithm 1256*f0865ec9SKyle Evans */ 1257*f0865ec9SKyle Evans pos = (ret) ? ((i % (k - 2)) + 2) : pos; 1258*f0865ec9SKyle Evans for(i = 2; i < k; i++){ 1259*f0865ec9SKyle Evans u8 r_; 1260*f0865ec9SKyle Evans unsigned int idx; 1261*f0865ec9SKyle Evans /* Replace m by a random value in case of error */ 1262*f0865ec9SKyle Evans idx = ((i < pos) ? 0x00 : (i - pos)); 1263*f0865ec9SKyle Evans r ^= (u8)i; 1264*f0865ec9SKyle Evans r_ = (u8)((u8)(!!ret) * r); 1265*f0865ec9SKyle Evans m[idx] = (em[i] ^ r_); 1266*f0865ec9SKyle Evans } 1267*f0865ec9SKyle Evans (*mlen) = (u16)(k - pos); 1268*f0865ec9SKyle Evans /* Hide return value details to avoid information leak */ 1269*f0865ec9SKyle Evans ret = -(!!ret); 1270*f0865ec9SKyle Evans 1271*f0865ec9SKyle Evans err: 1272*f0865ec9SKyle Evans nn_uninit(&m_); 1273*f0865ec9SKyle Evans nn_uninit(&c_); 1274*f0865ec9SKyle Evans 1275*f0865ec9SKyle Evans return ret; 1276*f0865ec9SKyle Evans } 1277*f0865ec9SKyle Evans 1278*f0865ec9SKyle Evans /* 1279*f0865ec9SKyle Evans * Basic version without much SCA/faults protections. 1280*f0865ec9SKyle Evans */ 1281*f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_decrypt(const rsa_priv_key *priv, const u8 *c, u32 clen, 1282*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits) 1283*f0865ec9SKyle Evans { 1284*f0865ec9SKyle Evans return _rsaes_pkcs1_v1_5_decrypt(priv, NULL, c, clen, m, mlen, modbits); 1285*f0865ec9SKyle Evans } 1286*f0865ec9SKyle Evans 1287*f0865ec9SKyle Evans /* 1288*f0865ec9SKyle Evans * Hardened version with some SCA/faults protections. 1289*f0865ec9SKyle Evans */ 1290*f0865ec9SKyle Evans int rsaes_pkcs1_v1_5_decrypt_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen, 1291*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits) 1292*f0865ec9SKyle Evans { 1293*f0865ec9SKyle Evans return _rsaes_pkcs1_v1_5_decrypt(priv, pub, c, clen, m, mlen, modbits); 1294*f0865ec9SKyle Evans } 1295*f0865ec9SKyle Evans 1296*f0865ec9SKyle Evans /* The RSAES-OAEP-ENCRYPT algorithm as described in RFC 8017 section 7.1.1 1297*f0865ec9SKyle Evans * 1298*f0865ec9SKyle Evans */ 1299*f0865ec9SKyle Evans int rsaes_oaep_encrypt(const rsa_pub_key *pub, const u8 *m, u32 mlen, 1300*f0865ec9SKyle Evans u8 *c, u32 *clen, u32 modbits, const u8 *label, u32 label_len, 1301*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 1302*f0865ec9SKyle Evans const u8 *forced_seed, u32 seedlen) 1303*f0865ec9SKyle Evans { 1304*f0865ec9SKyle Evans int ret; 1305*f0865ec9SKyle Evans u32 k, pslen, khlen; 1306*f0865ec9SKyle Evans unsigned int i; 1307*f0865ec9SKyle Evans u8 hlen, block_size; 1308*f0865ec9SKyle Evans u8 *em = c; 1309*f0865ec9SKyle Evans /* Reasonable sizes */ 1310*f0865ec9SKyle Evans u8 seed[MAX_DIGEST_SIZE]; 1311*f0865ec9SKyle Evans /* 1312*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 1313*f0865ec9SKyle Evans */ 1314*f0865ec9SKyle Evans u8 dbmask[NN_USABLE_MAX_BYTE_LEN]; 1315*f0865ec9SKyle Evans u8 db[NN_USABLE_MAX_BYTE_LEN]; 1316*f0865ec9SKyle Evans u8 *seedmask = dbmask, *maskedseed = NULL, *maskeddb = NULL; 1317*f0865ec9SKyle Evans const u8 *input[2] = { c, NULL }; 1318*f0865ec9SKyle Evans u32 ilens[2] = { 0, 0 }; 1319*f0865ec9SKyle Evans nn m_, c_; 1320*f0865ec9SKyle Evans m_.magic = c_.magic = WORD(0); 1321*f0865ec9SKyle Evans 1322*f0865ec9SKyle Evans /* Zeroize local variables */ 1323*f0865ec9SKyle Evans ret = local_memset(seed, 0, sizeof(seed)); EG(ret, err); 1324*f0865ec9SKyle Evans ret = local_memset(db, 0, sizeof(db)); EG(ret, err); 1325*f0865ec9SKyle Evans ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err); 1326*f0865ec9SKyle Evans 1327*f0865ec9SKyle Evans MUST_HAVE((clen != NULL) && (c != NULL) && (m != NULL), ret, err); 1328*f0865ec9SKyle Evans 1329*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1330*f0865ec9SKyle Evans 1331*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 1332*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 1333*f0865ec9SKyle Evans 1334*f0865ec9SKyle Evans /* Check on lengths */ 1335*f0865ec9SKyle Evans MUST_HAVE(((u32)k >= ((2 * (u32)hlen) + 2)), ret, err); 1336*f0865ec9SKyle Evans MUST_HAVE(((mlen ) <= ((u32)k - (2 * (u32)hlen) - 2)), ret, err); 1337*f0865ec9SKyle Evans MUST_HAVE(((*clen) >= k), ret, err); 1338*f0865ec9SKyle Evans 1339*f0865ec9SKyle Evans /* EME-OAEP encoding: DB = lHash || PS || 0x01 || M */ 1340*f0865ec9SKyle Evans /* and then EM = 0x00 || maskedSeed || maskedDB */ 1341*f0865ec9SKyle Evans maskedseed = &em[1]; 1342*f0865ec9SKyle Evans maskeddb = &em[hlen + 1]; 1343*f0865ec9SKyle Evans MUST_HAVE(((k - hlen - 1) <= sizeof(db)), ret, err); 1344*f0865ec9SKyle Evans if(label == NULL){ 1345*f0865ec9SKyle Evans MUST_HAVE((label_len == 0), ret, err); 1346*f0865ec9SKyle Evans } 1347*f0865ec9SKyle Evans else{ 1348*f0865ec9SKyle Evans input[0] = label; 1349*f0865ec9SKyle Evans ilens[0] = label_len; 1350*f0865ec9SKyle Evans } 1351*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, &db[0], gen_hash_type); EG(ret, err); 1352*f0865ec9SKyle Evans /* 1353*f0865ec9SKyle Evans * 2.b. Generate a padding string PS consisting of k - mLen - 2hLen - 1354*f0865ec9SKyle Evans * 2 zero octets. The length of PS may be zero. 1355*f0865ec9SKyle Evans * 1356*f0865ec9SKyle Evans * DB = lHash || PS || 0x01 || M. Hence, PS starts at octet hlen in DB 1357*f0865ec9SKyle Evans */ 1358*f0865ec9SKyle Evans pslen = (k - mlen - (u32)(2 * hlen) - 2); 1359*f0865ec9SKyle Evans for(i = 0; i < pslen; i++){ 1360*f0865ec9SKyle Evans db[hlen + i] = 0x00; 1361*f0865ec9SKyle Evans } 1362*f0865ec9SKyle Evans /* 0x01 || M */ 1363*f0865ec9SKyle Evans db[hlen + pslen] = 0x01; 1364*f0865ec9SKyle Evans for(i = 0 ; i < mlen; i++){ 1365*f0865ec9SKyle Evans db[hlen + pslen + 1 + i] = m[i]; 1366*f0865ec9SKyle Evans } 1367*f0865ec9SKyle Evans /* Generate a random octet string seed of length hLen */ 1368*f0865ec9SKyle Evans MUST_HAVE((hlen <= sizeof(seed)), ret, err); 1369*f0865ec9SKyle Evans if(forced_seed != NULL){ 1370*f0865ec9SKyle Evans MUST_HAVE((seedlen == hlen), ret, err); 1371*f0865ec9SKyle Evans ret = local_memcpy(seed, forced_seed, seedlen); EG(ret, err); 1372*f0865ec9SKyle Evans } 1373*f0865ec9SKyle Evans else{ 1374*f0865ec9SKyle Evans ret = get_random(seed, hlen); EG(ret, err); 1375*f0865ec9SKyle Evans } 1376*f0865ec9SKyle Evans /* Let dbMask = MGF(seed, k - hLen - 1)*/ 1377*f0865ec9SKyle Evans khlen = (k - hlen - 1); 1378*f0865ec9SKyle Evans MUST_HAVE((khlen <= sizeof(dbmask)), ret, err); 1379*f0865ec9SKyle Evans ret = _mgf1(seed, hlen, dbmask, khlen, mgf_hash_type); EG(ret, err); 1380*f0865ec9SKyle Evans /* Let maskedDB = DB \xor dbMask */ 1381*f0865ec9SKyle Evans for(i = 0; i < khlen; i++){ 1382*f0865ec9SKyle Evans maskeddb[i] = (db[i] ^ dbmask[i]); 1383*f0865ec9SKyle Evans } 1384*f0865ec9SKyle Evans /* Let seedMask = MGF(maskedDB, hLen) */ 1385*f0865ec9SKyle Evans MUST_HAVE((khlen < (u32)((u32)0x1 << 16)), ret, err); 1386*f0865ec9SKyle Evans ret = _mgf1(maskeddb, (u16)khlen, seedmask, hlen, mgf_hash_type); EG(ret, err); 1387*f0865ec9SKyle Evans /* Let maskedSeed = seed \xor seedMask */ 1388*f0865ec9SKyle Evans for(i = 0; i < hlen; i++){ 1389*f0865ec9SKyle Evans maskedseed[i] = (seed[i] ^ seedmask[i]); 1390*f0865ec9SKyle Evans } 1391*f0865ec9SKyle Evans /* EM = 0x00 || maskedSeed || maskedDB should be filled */ 1392*f0865ec9SKyle Evans em[0] = 0x00; 1393*f0865ec9SKyle Evans 1394*f0865ec9SKyle Evans /* RSA encryption */ 1395*f0865ec9SKyle Evans /* m = OS2IP (EM) */ 1396*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1397*f0865ec9SKyle Evans ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err); 1398*f0865ec9SKyle Evans /* c = RSAEP ((n, e), m) */ 1399*f0865ec9SKyle Evans ret = rsaep(pub, &m_, &c_); EG(ret, err); 1400*f0865ec9SKyle Evans /* C = I2OSP (c, k) */ 1401*f0865ec9SKyle Evans ret = rsa_i2osp(&c_, c, (u16)k); EG(ret, err); 1402*f0865ec9SKyle Evans (*clen) = (u16)k; 1403*f0865ec9SKyle Evans 1404*f0865ec9SKyle Evans err: 1405*f0865ec9SKyle Evans nn_uninit(&m_); 1406*f0865ec9SKyle Evans nn_uninit(&c_); 1407*f0865ec9SKyle Evans /* Zeroify in case of error */ 1408*f0865ec9SKyle Evans if(ret && (clen != NULL)){ 1409*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(c, 0, (*clen))); 1410*f0865ec9SKyle Evans } 1411*f0865ec9SKyle Evans 1412*f0865ec9SKyle Evans return ret; 1413*f0865ec9SKyle Evans } 1414*f0865ec9SKyle Evans 1415*f0865ec9SKyle Evans /* The RSAES-OAEP-DECRYPT algorithm as described in RFC 8017 section 7.1.2 1416*f0865ec9SKyle Evans * 1417*f0865ec9SKyle Evans */ 1418*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsaes_oaep_decrypt(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen, 1419*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits, 1420*f0865ec9SKyle Evans const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type, 1421*f0865ec9SKyle Evans gen_hash_alg_type mgf_hash_type) 1422*f0865ec9SKyle Evans { 1423*f0865ec9SKyle Evans int ret, cmp; 1424*f0865ec9SKyle Evans u32 k, khlen; 1425*f0865ec9SKyle Evans unsigned int i, pos; 1426*f0865ec9SKyle Evans u8 hlen, block_size; 1427*f0865ec9SKyle Evans u8 *em = m; 1428*f0865ec9SKyle Evans u8 r; 1429*f0865ec9SKyle Evans /* Reasonable sizes */ 1430*f0865ec9SKyle Evans u8 lhash[MAX_DIGEST_SIZE]; 1431*f0865ec9SKyle Evans u8 seedmask[MAX_DIGEST_SIZE]; 1432*f0865ec9SKyle Evans /* 1433*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 1434*f0865ec9SKyle Evans */ 1435*f0865ec9SKyle Evans u8 dbmask[NN_USABLE_MAX_BYTE_LEN]; 1436*f0865ec9SKyle Evans u8 *seed = seedmask, *maskedseed = NULL, *maskeddb = NULL, *db = NULL; 1437*f0865ec9SKyle Evans const u8 *input[2] = { c, NULL }; 1438*f0865ec9SKyle Evans u32 ilens[2] = { 0, 0 }; 1439*f0865ec9SKyle Evans nn m_, c_; 1440*f0865ec9SKyle Evans m_.magic = c_.magic = WORD(0); 1441*f0865ec9SKyle Evans 1442*f0865ec9SKyle Evans /* Zeroize local variables */ 1443*f0865ec9SKyle Evans ret = local_memset(lhash, 0, sizeof(lhash)); EG(ret, err); 1444*f0865ec9SKyle Evans ret = local_memset(seedmask, 0, sizeof(seedmask)); EG(ret, err); 1445*f0865ec9SKyle Evans ret = local_memset(dbmask, 0, sizeof(dbmask)); EG(ret, err); 1446*f0865ec9SKyle Evans 1447*f0865ec9SKyle Evans MUST_HAVE((c != NULL) && (m != NULL), ret, err); 1448*f0865ec9SKyle Evans 1449*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1450*f0865ec9SKyle Evans 1451*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 1452*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 1453*f0865ec9SKyle Evans 1454*f0865ec9SKyle Evans /* Check on lengths */ 1455*f0865ec9SKyle Evans MUST_HAVE((clen == k), ret, err); 1456*f0865ec9SKyle Evans MUST_HAVE(((u32)k >= ((2 * (u32)hlen) + 2)), ret, err); 1457*f0865ec9SKyle Evans 1458*f0865ec9SKyle Evans /* RSA decryption */ 1459*f0865ec9SKyle Evans /* c = OS2IP (C) */ 1460*f0865ec9SKyle Evans ret = rsa_os2ip(&c_, c, clen); EG(ret, err); 1461*f0865ec9SKyle Evans /* m = RSADP ((n, d), c) */ 1462*f0865ec9SKyle Evans if(pub != NULL){ 1463*f0865ec9SKyle Evans ret = rsadp_hardened(priv, pub, &c_, &m_); EG(ret, err); 1464*f0865ec9SKyle Evans } 1465*f0865ec9SKyle Evans else{ 1466*f0865ec9SKyle Evans ret = rsadp(priv, &c_, &m_); EG(ret, err); 1467*f0865ec9SKyle Evans } 1468*f0865ec9SKyle Evans /* EM = I2OSP (m, k) */ 1469*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1470*f0865ec9SKyle Evans ret = rsa_i2osp(&m_, em, (u16)k); EG(ret, err); 1471*f0865ec9SKyle Evans 1472*f0865ec9SKyle Evans /* EME-OAEP decoding */ 1473*f0865ec9SKyle Evans /* lHash = Hash(L) */ 1474*f0865ec9SKyle Evans if(label == NULL){ 1475*f0865ec9SKyle Evans MUST_HAVE((label_len == 0), ret, err); 1476*f0865ec9SKyle Evans } 1477*f0865ec9SKyle Evans else{ 1478*f0865ec9SKyle Evans input[0] = label; 1479*f0865ec9SKyle Evans ilens[0] = label_len; 1480*f0865ec9SKyle Evans } 1481*f0865ec9SKyle Evans ret = gen_hash_hfunc_scattered(input, ilens, lhash, gen_hash_type); EG(ret, err); 1482*f0865ec9SKyle Evans /* EM = Y || maskedSeed || maskedDB */ 1483*f0865ec9SKyle Evans maskedseed = &em[1]; 1484*f0865ec9SKyle Evans maskeddb = &em[hlen + 1]; 1485*f0865ec9SKyle Evans /* seedMask = MGF(maskedDB, hLen) */ 1486*f0865ec9SKyle Evans khlen = (k - hlen - 1); 1487*f0865ec9SKyle Evans MUST_HAVE((khlen < (u32)((u32)0x1 << 16)), ret, err); 1488*f0865ec9SKyle Evans ret = _mgf1(maskeddb, (u16)khlen, seedmask, hlen, mgf_hash_type); EG(ret, err); 1489*f0865ec9SKyle Evans /* Let maskedSeed = seed \xor seedMask */ 1490*f0865ec9SKyle Evans for(i = 0; i < hlen; i++){ 1491*f0865ec9SKyle Evans seed[i] = (maskedseed[i] ^ seedmask[i]); 1492*f0865ec9SKyle Evans } 1493*f0865ec9SKyle Evans /* dbMask = MGF(seed, k - hLen - 1) */ 1494*f0865ec9SKyle Evans MUST_HAVE((khlen <= sizeof(dbmask)), ret, err); 1495*f0865ec9SKyle Evans ret = _mgf1(seed, hlen, dbmask, khlen, mgf_hash_type); EG(ret, err); 1496*f0865ec9SKyle Evans /* Let DB = maskedDB \xor dbMask */ 1497*f0865ec9SKyle Evans db = dbmask; 1498*f0865ec9SKyle Evans for(i = 0; i < khlen; i++){ 1499*f0865ec9SKyle Evans db[i] = (maskeddb[i] ^ dbmask[i]); 1500*f0865ec9SKyle Evans } 1501*f0865ec9SKyle Evans /* DB = lHash' || PS || 0x01 || M */ 1502*f0865ec9SKyle Evans /* NOTE: we try our best to do the following in constant time to 1503*f0865ec9SKyle Evans * limit padding oracles here (see Manger attacks). 1504*f0865ec9SKyle Evans */ 1505*f0865ec9SKyle Evans /* Y must be != 0 */ 1506*f0865ec9SKyle Evans ret = em[0]; 1507*f0865ec9SKyle Evans /* Isolate and compare lHash' to lHash */ 1508*f0865ec9SKyle Evans ret |= are_equal(&db[0], lhash, hlen, &cmp); 1509*f0865ec9SKyle Evans ret |= ((~cmp) & 0x1); 1510*f0865ec9SKyle Evans /* Find 0x01 separator in constant time */ 1511*f0865ec9SKyle Evans pos = 0; 1512*f0865ec9SKyle Evans for(i = hlen; i < khlen; i++){ 1513*f0865ec9SKyle Evans u8 r_; 1514*f0865ec9SKyle Evans pos = ((db[i] == 0x01) && (pos == 0)) ? i : pos; 1515*f0865ec9SKyle Evans r_ = (pos == 0) ? db[i] : 0; 1516*f0865ec9SKyle Evans ret |= r_; /* Capture non zero PS */ 1517*f0865ec9SKyle Evans } 1518*f0865ec9SKyle Evans pos = (pos == 0) ? pos : (pos + 1); 1519*f0865ec9SKyle Evans /* We get a random value between 2 and k if we have an error so that 1520*f0865ec9SKyle Evans * we put a random value in pos. 1521*f0865ec9SKyle Evans */ 1522*f0865ec9SKyle Evans ret |= get_random((u8*)&i, 4); 1523*f0865ec9SKyle Evans /* Get a random value r for later loop dummy operations */ 1524*f0865ec9SKyle Evans ret |= get_random(&r, 1); 1525*f0865ec9SKyle Evans /* Update pos with random value in case of error to progress 1526*f0865ec9SKyle Evans * nominally with the algorithm 1527*f0865ec9SKyle Evans */ 1528*f0865ec9SKyle Evans pos = (ret) ? ((i % (khlen - hlen)) + hlen) : pos; 1529*f0865ec9SKyle Evans /* Copy the result */ 1530*f0865ec9SKyle Evans for(i = hlen; i < khlen; i++){ 1531*f0865ec9SKyle Evans u8 r_; 1532*f0865ec9SKyle Evans unsigned int idx; 1533*f0865ec9SKyle Evans /* Replace m by a random value in case of error */ 1534*f0865ec9SKyle Evans idx = (i < pos) ? 0x00 : (i - pos); 1535*f0865ec9SKyle Evans r ^= (u8)i; 1536*f0865ec9SKyle Evans r_ = (u8)((u8)(!!ret) * r); 1537*f0865ec9SKyle Evans m[idx] = (db[i] ^ r_); 1538*f0865ec9SKyle Evans } 1539*f0865ec9SKyle Evans (*mlen) = (u16)(k - hlen - 1 - pos); 1540*f0865ec9SKyle Evans /* Hide return value details to avoid information leak */ 1541*f0865ec9SKyle Evans ret = -(!!ret); 1542*f0865ec9SKyle Evans 1543*f0865ec9SKyle Evans err: 1544*f0865ec9SKyle Evans nn_uninit(&m_); 1545*f0865ec9SKyle Evans nn_uninit(&c_); 1546*f0865ec9SKyle Evans 1547*f0865ec9SKyle Evans return ret; 1548*f0865ec9SKyle Evans } 1549*f0865ec9SKyle Evans 1550*f0865ec9SKyle Evans /* 1551*f0865ec9SKyle Evans * Basic version without much SCA/faults protections. 1552*f0865ec9SKyle Evans */ 1553*f0865ec9SKyle Evans int rsaes_oaep_decrypt(const rsa_priv_key *priv, const u8 *c, u32 clen, 1554*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits, 1555*f0865ec9SKyle Evans const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type, 1556*f0865ec9SKyle Evans gen_hash_alg_type mgf_hash_type) 1557*f0865ec9SKyle Evans { 1558*f0865ec9SKyle Evans return _rsaes_oaep_decrypt(priv, NULL, c, clen, m, mlen, modbits, label, label_len, gen_hash_type, mgf_hash_type); 1559*f0865ec9SKyle Evans } 1560*f0865ec9SKyle Evans 1561*f0865ec9SKyle Evans /* 1562*f0865ec9SKyle Evans * Hardened version with some SCA/faults protections. 1563*f0865ec9SKyle Evans */ 1564*f0865ec9SKyle Evans int rsaes_oaep_decrypt_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *c, u32 clen, 1565*f0865ec9SKyle Evans u8 *m, u32 *mlen, u32 modbits, 1566*f0865ec9SKyle Evans const u8 *label, u32 label_len, gen_hash_alg_type gen_hash_type, 1567*f0865ec9SKyle Evans gen_hash_alg_type mgf_hash_type) 1568*f0865ec9SKyle Evans { 1569*f0865ec9SKyle Evans return _rsaes_oaep_decrypt(priv, pub, c, clen, m, mlen, modbits, label, label_len, gen_hash_type, mgf_hash_type); 1570*f0865ec9SKyle Evans } 1571*f0865ec9SKyle Evans 1572*f0865ec9SKyle Evans /****************************************************************/ 1573*f0865ec9SKyle Evans /******** Signature schemes *************************************/ 1574*f0865ec9SKyle Evans /* The RSASSA-PKCS1-V1_5-SIGN signature algorithm as described in RFC 8017 section 8.2.1 1575*f0865ec9SKyle Evans * 1576*f0865ec9SKyle Evans */ 1577*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsassa_pkcs1_v1_5_sign(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen, 1578*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type) 1579*f0865ec9SKyle Evans { 1580*f0865ec9SKyle Evans int ret; 1581*f0865ec9SKyle Evans u8 *em = s; 1582*f0865ec9SKyle Evans u32 k; 1583*f0865ec9SKyle Evans nn m_, s_; 1584*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1585*f0865ec9SKyle Evans 1586*f0865ec9SKyle Evans /* Checks on sizes */ 1587*f0865ec9SKyle Evans MUST_HAVE((slen != NULL), ret, err); 1588*f0865ec9SKyle Evans 1589*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1590*f0865ec9SKyle Evans 1591*f0865ec9SKyle Evans /* Only accept reasonable sizes */ 1592*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1593*f0865ec9SKyle Evans /* Sanity check on size */ 1594*f0865ec9SKyle Evans MUST_HAVE(((*slen) >= k), ret, err); 1595*f0865ec9SKyle Evans 1596*f0865ec9SKyle Evans /* EM = EMSA-PKCS1-V1_5-ENCODE (M, k) */ 1597*f0865ec9SKyle Evans ret = emsa_pkcs1_v1_5_encode(m, mlen, em, (u16)k, gen_hash_type); EG(ret, err); 1598*f0865ec9SKyle Evans 1599*f0865ec9SKyle Evans /* m = OS2IP (EM) */ 1600*f0865ec9SKyle Evans ret = rsa_os2ip(&m_, em, (u16)k); EG(ret, err); 1601*f0865ec9SKyle Evans /* s = RSASP1 (K, m) */ 1602*f0865ec9SKyle Evans if(pub != NULL){ 1603*f0865ec9SKyle Evans ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err); 1604*f0865ec9SKyle Evans } 1605*f0865ec9SKyle Evans else{ 1606*f0865ec9SKyle Evans ret = rsasp1(priv, &m_, &s_); EG(ret, err); 1607*f0865ec9SKyle Evans } 1608*f0865ec9SKyle Evans /* S = I2OSP (s, k) */ 1609*f0865ec9SKyle Evans ret = rsa_i2osp(&s_, s, (u16)k); 1610*f0865ec9SKyle Evans (*slen) = (u16)k; 1611*f0865ec9SKyle Evans 1612*f0865ec9SKyle Evans err: 1613*f0865ec9SKyle Evans nn_uninit(&m_); 1614*f0865ec9SKyle Evans nn_uninit(&s_); 1615*f0865ec9SKyle Evans /* Zeroify in case of error */ 1616*f0865ec9SKyle Evans if(ret && (slen != NULL)){ 1617*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(s, 0, (*slen))); 1618*f0865ec9SKyle Evans } 1619*f0865ec9SKyle Evans 1620*f0865ec9SKyle Evans return ret; 1621*f0865ec9SKyle Evans } 1622*f0865ec9SKyle Evans 1623*f0865ec9SKyle Evans /* 1624*f0865ec9SKyle Evans * Basic version without much SCA/faults protections. 1625*f0865ec9SKyle Evans */ 1626*f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_sign(const rsa_priv_key *priv, const u8 *m, u32 mlen, 1627*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type) 1628*f0865ec9SKyle Evans { 1629*f0865ec9SKyle Evans return _rsassa_pkcs1_v1_5_sign(priv, NULL, m, mlen, s, slen, modbits, gen_hash_type); 1630*f0865ec9SKyle Evans } 1631*f0865ec9SKyle Evans 1632*f0865ec9SKyle Evans /* 1633*f0865ec9SKyle Evans * Hardened version with some SCA/faults protections. 1634*f0865ec9SKyle Evans */ 1635*f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_sign_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen, 1636*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, gen_hash_alg_type gen_hash_type) 1637*f0865ec9SKyle Evans { 1638*f0865ec9SKyle Evans return _rsassa_pkcs1_v1_5_sign(priv, pub, m, mlen, s, slen, modbits, gen_hash_type); 1639*f0865ec9SKyle Evans } 1640*f0865ec9SKyle Evans 1641*f0865ec9SKyle Evans /* The RSASSA-PKCS1-V1_5-VERIFY verification algorithm as described in RFC 8017 section 8.2.2 1642*f0865ec9SKyle Evans * 1643*f0865ec9SKyle Evans */ 1644*f0865ec9SKyle Evans int rsassa_pkcs1_v1_5_verify(const rsa_pub_key *pub, const u8 *m, u32 mlen, 1645*f0865ec9SKyle Evans const u8 *s, u16 slen, u32 modbits, gen_hash_alg_type gen_hash_type) 1646*f0865ec9SKyle Evans { 1647*f0865ec9SKyle Evans int ret, cmp; 1648*f0865ec9SKyle Evans /* Get a large enough buffer to hold the result */ 1649*f0865ec9SKyle Evans /* 1650*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 1651*f0865ec9SKyle Evans */ 1652*f0865ec9SKyle Evans u8 em[NN_USABLE_MAX_BYTE_LEN]; 1653*f0865ec9SKyle Evans u8 em_[NN_USABLE_MAX_BYTE_LEN]; 1654*f0865ec9SKyle Evans u32 k; 1655*f0865ec9SKyle Evans nn m_, s_; 1656*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1657*f0865ec9SKyle Evans 1658*f0865ec9SKyle Evans /* Zeroize local variables */ 1659*f0865ec9SKyle Evans ret = local_memset(em, 0, sizeof(em)); EG(ret, err); 1660*f0865ec9SKyle Evans ret = local_memset(em_, 0, sizeof(em_)); EG(ret, err); 1661*f0865ec9SKyle Evans 1662*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1663*f0865ec9SKyle Evans /* Only accept reasonable sizes */ 1664*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1665*f0865ec9SKyle Evans 1666*f0865ec9SKyle Evans /* Length checking: If the length of the signature S is not k 1667*f0865ec9SKyle Evans * octets, output "invalid signature" and stop. 1668*f0865ec9SKyle Evans */ 1669*f0865ec9SKyle Evans MUST_HAVE(((u16)k == slen), ret, err); 1670*f0865ec9SKyle Evans 1671*f0865ec9SKyle Evans /* s = OS2IP (S) */ 1672*f0865ec9SKyle Evans ret = rsa_os2ip(&s_, s, slen); EG(ret, err); 1673*f0865ec9SKyle Evans /* m = RSAVP1 ((n, e), s) */ 1674*f0865ec9SKyle Evans ret = rsavp1(pub, &s_, &m_); EG(ret, err); 1675*f0865ec9SKyle Evans /* EM = I2OSP (m, k) */ 1676*f0865ec9SKyle Evans MUST_HAVE((slen <= sizeof(em)), ret, err); 1677*f0865ec9SKyle Evans ret = rsa_i2osp(&m_, em, slen); EG(ret, err); 1678*f0865ec9SKyle Evans /* EM' = EMSA-PKCS1-V1_5-ENCODE (M, k) */ 1679*f0865ec9SKyle Evans MUST_HAVE((k <= sizeof(em_)), ret, err); 1680*f0865ec9SKyle Evans ret = emsa_pkcs1_v1_5_encode(m, mlen, em_, (u16)k, gen_hash_type); EG(ret, err); 1681*f0865ec9SKyle Evans 1682*f0865ec9SKyle Evans /* Compare */ 1683*f0865ec9SKyle Evans ret = are_equal(em, em_, (u16)k, &cmp); EG(ret, err); 1684*f0865ec9SKyle Evans if(!cmp){ 1685*f0865ec9SKyle Evans ret = -1; 1686*f0865ec9SKyle Evans } 1687*f0865ec9SKyle Evans err: 1688*f0865ec9SKyle Evans nn_uninit(&m_); 1689*f0865ec9SKyle Evans nn_uninit(&s_); 1690*f0865ec9SKyle Evans 1691*f0865ec9SKyle Evans return ret; 1692*f0865ec9SKyle Evans } 1693*f0865ec9SKyle Evans 1694*f0865ec9SKyle Evans /* The RSASSA-PSS-SIGN signature algorithm as described in RFC 8017 section 8.1.1 1695*f0865ec9SKyle Evans * 1696*f0865ec9SKyle Evans */ 1697*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsassa_pss_sign(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen, 1698*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, 1699*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 1700*f0865ec9SKyle Evans u32 saltlen, const u8 *forced_salt) 1701*f0865ec9SKyle Evans { 1702*f0865ec9SKyle Evans int ret; 1703*f0865ec9SKyle Evans u8 *em = s; 1704*f0865ec9SKyle Evans u16 emsize; 1705*f0865ec9SKyle Evans u32 k; 1706*f0865ec9SKyle Evans nn m_, s_; 1707*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1708*f0865ec9SKyle Evans 1709*f0865ec9SKyle Evans MUST_HAVE((slen != NULL), ret, err); 1710*f0865ec9SKyle Evans 1711*f0865ec9SKyle Evans MUST_HAVE((modbits > 1), ret, err); 1712*f0865ec9SKyle Evans 1713*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1714*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1715*f0865ec9SKyle Evans 1716*f0865ec9SKyle Evans /* Sanity check on size */ 1717*f0865ec9SKyle Evans MUST_HAVE(((*slen) >= k), ret, err); 1718*f0865ec9SKyle Evans 1719*f0865ec9SKyle Evans /* EM = EMSA-PSS-ENCODE (M, modBits - 1) */ 1720*f0865ec9SKyle Evans emsize = (*slen); 1721*f0865ec9SKyle Evans ret = emsa_pss_encode(m, mlen, em, (modbits - 1), &emsize, gen_hash_type, mgf_hash_type, saltlen, forced_salt); EG(ret, err); 1722*f0865ec9SKyle Evans 1723*f0865ec9SKyle Evans /* Note that the octet length of EM will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise */ 1724*f0865ec9SKyle Evans MUST_HAVE(emsize == BYTECEIL(modbits - 1), ret, err); 1725*f0865ec9SKyle Evans 1726*f0865ec9SKyle Evans /* m = OS2IP (EM) */ 1727*f0865ec9SKyle Evans ret = rsa_os2ip(&m_, em, (u16)emsize); EG(ret, err); 1728*f0865ec9SKyle Evans /* s = RSASP1 (K, m) */ 1729*f0865ec9SKyle Evans if(pub != NULL){ 1730*f0865ec9SKyle Evans ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err); 1731*f0865ec9SKyle Evans } 1732*f0865ec9SKyle Evans else{ 1733*f0865ec9SKyle Evans ret = rsasp1(priv, &m_, &s_); EG(ret, err); 1734*f0865ec9SKyle Evans } 1735*f0865ec9SKyle Evans /* S = I2OSP (s, k) */ 1736*f0865ec9SKyle Evans MUST_HAVE((k < ((u32)0x1 << 16)), ret, err); 1737*f0865ec9SKyle Evans ret = rsa_i2osp(&s_, s, (u16)k); 1738*f0865ec9SKyle Evans (*slen) = (u16)k; 1739*f0865ec9SKyle Evans 1740*f0865ec9SKyle Evans err: 1741*f0865ec9SKyle Evans nn_uninit(&m_); 1742*f0865ec9SKyle Evans nn_uninit(&s_); 1743*f0865ec9SKyle Evans /* Zeroify in case of error */ 1744*f0865ec9SKyle Evans if(ret && (slen != NULL)){ 1745*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(s, 0, (*slen))); 1746*f0865ec9SKyle Evans } 1747*f0865ec9SKyle Evans 1748*f0865ec9SKyle Evans return ret; 1749*f0865ec9SKyle Evans } 1750*f0865ec9SKyle Evans 1751*f0865ec9SKyle Evans /* 1752*f0865ec9SKyle Evans * Basic version without much SCA/faults protections. 1753*f0865ec9SKyle Evans */ 1754*f0865ec9SKyle Evans int rsassa_pss_sign(const rsa_priv_key *priv, const u8 *m, u32 mlen, 1755*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, 1756*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 1757*f0865ec9SKyle Evans u32 saltlen, const u8 *forced_salt) 1758*f0865ec9SKyle Evans { 1759*f0865ec9SKyle Evans return _rsassa_pss_sign(priv, NULL, m, mlen, s, slen, modbits, gen_hash_type, mgf_hash_type, saltlen, forced_salt); 1760*f0865ec9SKyle Evans } 1761*f0865ec9SKyle Evans 1762*f0865ec9SKyle Evans /* 1763*f0865ec9SKyle Evans * Hardened version with some SCA/faults protections. 1764*f0865ec9SKyle Evans */ 1765*f0865ec9SKyle Evans int rsassa_pss_sign_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, const u8 *m, u32 mlen, 1766*f0865ec9SKyle Evans u8 *s, u16 *slen, u32 modbits, 1767*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 1768*f0865ec9SKyle Evans u32 saltlen, const u8 *forced_salt) 1769*f0865ec9SKyle Evans { 1770*f0865ec9SKyle Evans return _rsassa_pss_sign(priv, pub, m, mlen, s, slen, modbits, gen_hash_type, mgf_hash_type, saltlen, forced_salt); 1771*f0865ec9SKyle Evans } 1772*f0865ec9SKyle Evans 1773*f0865ec9SKyle Evans 1774*f0865ec9SKyle Evans /* The RSASSA-PSS-VERIFY verification algorithm as described in RFC 8017 section 8.1.2 1775*f0865ec9SKyle Evans * 1776*f0865ec9SKyle Evans */ 1777*f0865ec9SKyle Evans int rsassa_pss_verify(const rsa_pub_key *pub, const u8 *m, u32 mlen, 1778*f0865ec9SKyle Evans const u8 *s, u16 slen, u32 modbits, 1779*f0865ec9SKyle Evans gen_hash_alg_type gen_hash_type, gen_hash_alg_type mgf_hash_type, 1780*f0865ec9SKyle Evans u32 saltlen) 1781*f0865ec9SKyle Evans { 1782*f0865ec9SKyle Evans int ret; 1783*f0865ec9SKyle Evans /* Get a large enough buffer to hold the result */ 1784*f0865ec9SKyle Evans /* 1785*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 1786*f0865ec9SKyle Evans */ 1787*f0865ec9SKyle Evans u8 em[NN_USABLE_MAX_BYTE_LEN]; 1788*f0865ec9SKyle Evans u16 emlen; 1789*f0865ec9SKyle Evans u32 k; 1790*f0865ec9SKyle Evans nn m_, s_; 1791*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1792*f0865ec9SKyle Evans 1793*f0865ec9SKyle Evans /* Zeroize local variables */ 1794*f0865ec9SKyle Evans ret = local_memset(em, 0, sizeof(em)); EG(ret, err); 1795*f0865ec9SKyle Evans 1796*f0865ec9SKyle Evans MUST_HAVE((modbits > 1), ret, err); 1797*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1798*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1799*f0865ec9SKyle Evans 1800*f0865ec9SKyle Evans /* s = OS2IP (S) */ 1801*f0865ec9SKyle Evans ret = rsa_os2ip(&s_, s, slen); EG(ret, err); 1802*f0865ec9SKyle Evans /* m = RSAVP1 ((n, e), s) */ 1803*f0865ec9SKyle Evans ret = rsavp1(pub, &s_, &m_); EG(ret, err); 1804*f0865ec9SKyle Evans /* emLen = \ceil ((modBits - 1)/8) */ 1805*f0865ec9SKyle Evans MUST_HAVE((((modbits - 1) / 8) + 1) < (u32)((u32)0x1 << 16), ret, err); 1806*f0865ec9SKyle Evans emlen = (((modbits - 1) % 8) == 0) ? (u16)((modbits - 1) / 8) : (u16)(((modbits - 1) / 8) + 1); 1807*f0865ec9SKyle Evans 1808*f0865ec9SKyle Evans /* Note that emLen will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise */ 1809*f0865ec9SKyle Evans MUST_HAVE(emlen == BYTECEIL(modbits - 1), ret, err); 1810*f0865ec9SKyle Evans 1811*f0865ec9SKyle Evans /* EM = I2OSP (m, emLen) */ 1812*f0865ec9SKyle Evans MUST_HAVE((emlen <= sizeof(em)), ret, err); 1813*f0865ec9SKyle Evans ret = rsa_i2osp(&m_, em, (u16)emlen); EG(ret, err); 1814*f0865ec9SKyle Evans /* Result = EMSA-PSS-VERIFY (M, EM, modBits - 1) */ 1815*f0865ec9SKyle Evans ret = emsa_pss_verify(m, mlen, em, (modbits - 1), emlen, gen_hash_type, mgf_hash_type, saltlen); 1816*f0865ec9SKyle Evans 1817*f0865ec9SKyle Evans err: 1818*f0865ec9SKyle Evans nn_uninit(&m_); 1819*f0865ec9SKyle Evans nn_uninit(&s_); 1820*f0865ec9SKyle Evans 1821*f0865ec9SKyle Evans return ret; 1822*f0865ec9SKyle Evans } 1823*f0865ec9SKyle Evans 1824*f0865ec9SKyle Evans /* The RSA signature algorithm using ISO/IEC 9796-2 padding scheme 1. 1825*f0865ec9SKyle Evans * This is a signature with recovery. 1826*f0865ec9SKyle Evans * 1827*f0865ec9SKyle Evans * XXX: beware that this scheme is here for completeness, but is considered fragile 1828*f0865ec9SKyle Evans * since practical attacks exist when the hash function is of relatively "small" size 1829*f0865ec9SKyle Evans * (see http://www.crypto-uni.lu/jscoron/publications/iso97962joc.pdf). 1830*f0865ec9SKyle Evans * 1831*f0865ec9SKyle Evans * The ISO/IEC 9796-2 is also described in EMV Book 2 in the A.2.1 section: 1832*f0865ec9SKyle Evans * "Digital Signature Scheme Giving Message Recovery". 1833*f0865ec9SKyle Evans * 1834*f0865ec9SKyle Evans */ 1835*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _rsa_iso9796_2_sign_recover(const rsa_priv_key *priv, const rsa_pub_key *pub, 1836*f0865ec9SKyle Evans const u8 *m, u32 mlen, u32 *m1len, u32 *m2len, u8 *s, u16 *slen, 1837*f0865ec9SKyle Evans u32 modbits, gen_hash_alg_type gen_hash_type) 1838*f0865ec9SKyle Evans { 1839*f0865ec9SKyle Evans int ret; 1840*f0865ec9SKyle Evans u32 k, m1len_, m2len_; 1841*f0865ec9SKyle Evans u8 hlen, block_size; 1842*f0865ec9SKyle Evans gen_hash_context hctx; 1843*f0865ec9SKyle Evans nn m_, s_; 1844*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1845*f0865ec9SKyle Evans 1846*f0865ec9SKyle Evans MUST_HAVE((priv != NULL) && (m != NULL), ret, err); 1847*f0865ec9SKyle Evans 1848*f0865ec9SKyle Evans MUST_HAVE((slen != NULL), ret, err); 1849*f0865ec9SKyle Evans 1850*f0865ec9SKyle Evans MUST_HAVE((modbits > 1), ret, err); 1851*f0865ec9SKyle Evans 1852*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1853*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1854*f0865ec9SKyle Evans 1855*f0865ec9SKyle Evans /* Get hash parameters */ 1856*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 1857*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 1858*f0865ec9SKyle Evans 1859*f0865ec9SKyle Evans /* Sanity check on sizes */ 1860*f0865ec9SKyle Evans MUST_HAVE(((*slen) >= k), ret, err); 1861*f0865ec9SKyle Evans MUST_HAVE(k >= (u32)(2 + hlen), ret, err); 1862*f0865ec9SKyle Evans 1863*f0865ec9SKyle Evans /* Compute our recoverable and non-recoverable parts */ 1864*f0865ec9SKyle Evans m1len_ = (mlen >= (k - 2 - hlen)) ? (k - 2 - hlen) : mlen; 1865*f0865ec9SKyle Evans m2len_ = (mlen - m1len_); 1866*f0865ec9SKyle Evans 1867*f0865ec9SKyle Evans /* Now hash the message */ 1868*f0865ec9SKyle Evans ret = gen_hash_init(&hctx, gen_hash_type); EG(ret, err); 1869*f0865ec9SKyle Evans ret = gen_hash_update(&hctx, m, mlen, gen_hash_type); EG(ret, err); 1870*f0865ec9SKyle Evans ret = gen_hash_final(&hctx, &s[k - 1 - hlen], gen_hash_type); EG(ret, err); 1871*f0865ec9SKyle Evans 1872*f0865ec9SKyle Evans /* Put M1 */ 1873*f0865ec9SKyle Evans ret = local_memcpy(&s[1], m, m1len_); EG(ret, err); 1874*f0865ec9SKyle Evans if(m1len != NULL){ 1875*f0865ec9SKyle Evans (*m1len) = m1len_; 1876*f0865ec9SKyle Evans } 1877*f0865ec9SKyle Evans if(m2len != NULL){ 1878*f0865ec9SKyle Evans (*m2len) = m2len_; 1879*f0865ec9SKyle Evans } 1880*f0865ec9SKyle Evans 1881*f0865ec9SKyle Evans /* Put the constants */ 1882*f0865ec9SKyle Evans s[0] = 0x6a; 1883*f0865ec9SKyle Evans s[k - 1] = 0xbc; 1884*f0865ec9SKyle Evans 1885*f0865ec9SKyle Evans /* m = OS2IP (X) */ 1886*f0865ec9SKyle Evans ret = rsa_os2ip(&m_, s, k); EG(ret, err); 1887*f0865ec9SKyle Evans /* s = RSASP1 (K, m) */ 1888*f0865ec9SKyle Evans if(pub != NULL){ 1889*f0865ec9SKyle Evans ret = rsasp1_hardened(priv, pub, &m_, &s_); EG(ret, err); 1890*f0865ec9SKyle Evans } 1891*f0865ec9SKyle Evans else{ 1892*f0865ec9SKyle Evans ret = rsasp1(priv, &m_, &s_); EG(ret, err); 1893*f0865ec9SKyle Evans } 1894*f0865ec9SKyle Evans /* S = I2OSP (s, k) */ 1895*f0865ec9SKyle Evans MUST_HAVE((k < ((u32)0x1 << 16)), ret, err); 1896*f0865ec9SKyle Evans ret = rsa_i2osp(&s_, s, (u16)k); 1897*f0865ec9SKyle Evans (*slen) = (u16)k; 1898*f0865ec9SKyle Evans 1899*f0865ec9SKyle Evans err: 1900*f0865ec9SKyle Evans nn_uninit(&m_); 1901*f0865ec9SKyle Evans nn_uninit(&s_); 1902*f0865ec9SKyle Evans 1903*f0865ec9SKyle Evans if(ret && (m1len != 0)){ 1904*f0865ec9SKyle Evans (*m1len) = 0; 1905*f0865ec9SKyle Evans } 1906*f0865ec9SKyle Evans if(ret && (m2len != 0)){ 1907*f0865ec9SKyle Evans (*m2len) = 0; 1908*f0865ec9SKyle Evans } 1909*f0865ec9SKyle Evans 1910*f0865ec9SKyle Evans return ret; 1911*f0865ec9SKyle Evans } 1912*f0865ec9SKyle Evans 1913*f0865ec9SKyle Evans /* 1914*f0865ec9SKyle Evans * Basic version without much SCA/faults protections. 1915*f0865ec9SKyle Evans */ 1916*f0865ec9SKyle Evans int rsa_iso9796_2_sign_recover(const rsa_priv_key *priv, const u8 *m, u32 mlen, u32 *m1len, 1917*f0865ec9SKyle Evans u32 *m2len, u8 *s, u16 *slen, 1918*f0865ec9SKyle Evans u32 modbits, gen_hash_alg_type gen_hash_type) 1919*f0865ec9SKyle Evans { 1920*f0865ec9SKyle Evans return _rsa_iso9796_2_sign_recover(priv, NULL, m, mlen, m1len, m2len, s, slen, modbits, gen_hash_type); 1921*f0865ec9SKyle Evans } 1922*f0865ec9SKyle Evans 1923*f0865ec9SKyle Evans /* 1924*f0865ec9SKyle Evans * Hardened version with some SCA/faults protections. 1925*f0865ec9SKyle Evans */ 1926*f0865ec9SKyle Evans int rsa_iso9796_2_sign_recover_hardened(const rsa_priv_key *priv, const rsa_pub_key *pub, 1927*f0865ec9SKyle Evans const u8 *m, u32 mlen, u32 *m1len, u32 *m2len, u8 *s, u16 *slen, 1928*f0865ec9SKyle Evans u32 modbits, gen_hash_alg_type gen_hash_type) 1929*f0865ec9SKyle Evans { 1930*f0865ec9SKyle Evans return _rsa_iso9796_2_sign_recover(priv, pub, m, mlen, m1len, m2len, s, slen, modbits, gen_hash_type); 1931*f0865ec9SKyle Evans } 1932*f0865ec9SKyle Evans 1933*f0865ec9SKyle Evans /* The RSA verification algorithm using ISO/IEC 9796-2 padding scheme 1. 1934*f0865ec9SKyle Evans * This is a verification with recovery. 1935*f0865ec9SKyle Evans * 1936*f0865ec9SKyle Evans * XXX: beware that this scheme is here for completeness, but is considered fragile 1937*f0865ec9SKyle Evans * since practical attacks exist when the hash function is of relatively "small" size 1938*f0865ec9SKyle Evans * (see http://www.crypto-uni.lu/jscoron/publications/iso97962joc.pdf). 1939*f0865ec9SKyle Evans * 1940*f0865ec9SKyle Evans * The ISO/IEC 9796-2 is also described in EMV Book 2 in the A.2.1 section: 1941*f0865ec9SKyle Evans * "Digital Signature Scheme Giving Message Recovery". 1942*f0865ec9SKyle Evans * 1943*f0865ec9SKyle Evans */ 1944*f0865ec9SKyle Evans int rsa_iso9796_2_verify_recover(const rsa_pub_key *pub, const u8 *m2, u32 m2len, u8 *m1, u32 *m1len, 1945*f0865ec9SKyle Evans const u8 *s, u16 slen, u32 modbits, gen_hash_alg_type gen_hash_type) 1946*f0865ec9SKyle Evans { 1947*f0865ec9SKyle Evans int ret, cmp; 1948*f0865ec9SKyle Evans /* Get a large enough buffer to hold the result */ 1949*f0865ec9SKyle Evans /* 1950*f0865ec9SKyle Evans * NOTE: the NN_USABLE_MAX_BYTE_LEN should be a reasonable size here. 1951*f0865ec9SKyle Evans */ 1952*f0865ec9SKyle Evans u8 X[NN_USABLE_MAX_BYTE_LEN]; 1953*f0865ec9SKyle Evans u8 H[MAX_DIGEST_SIZE]; 1954*f0865ec9SKyle Evans u32 k, m1len_; 1955*f0865ec9SKyle Evans u8 hlen, block_size; 1956*f0865ec9SKyle Evans gen_hash_context hctx; 1957*f0865ec9SKyle Evans nn m_, s_; 1958*f0865ec9SKyle Evans m_.magic = s_.magic = WORD(0); 1959*f0865ec9SKyle Evans 1960*f0865ec9SKyle Evans MUST_HAVE((pub != NULL) && (m2 != NULL), ret, err); 1961*f0865ec9SKyle Evans 1962*f0865ec9SKyle Evans /* Zeroize local variables */ 1963*f0865ec9SKyle Evans ret = local_memset(X, 0, sizeof(X)); EG(ret, err); 1964*f0865ec9SKyle Evans ret = local_memset(H, 0, sizeof(H)); EG(ret, err); 1965*f0865ec9SKyle Evans 1966*f0865ec9SKyle Evans k = BYTECEIL(modbits); 1967*f0865ec9SKyle Evans /* Only accept reasonable sizes */ 1968*f0865ec9SKyle Evans MUST_HAVE((k < (u32)((u32)0x1 << 16)), ret, err); 1969*f0865ec9SKyle Evans 1970*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(gen_hash_type, &hlen, &block_size); EG(ret, err); 1971*f0865ec9SKyle Evans MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err); 1972*f0865ec9SKyle Evans 1973*f0865ec9SKyle Evans /* Length checking: If the length of the signature S is not k 1974*f0865ec9SKyle Evans * octets, output "invalid signature" and stop. 1975*f0865ec9SKyle Evans */ 1976*f0865ec9SKyle Evans MUST_HAVE(((u16)k == slen), ret, err); 1977*f0865ec9SKyle Evans MUST_HAVE((slen >= (hlen + 2)), ret, err); 1978*f0865ec9SKyle Evans m1len_ = (u32)(slen - (hlen + 2)); 1979*f0865ec9SKyle Evans 1980*f0865ec9SKyle Evans /* s = OS2IP (S) */ 1981*f0865ec9SKyle Evans ret = rsa_os2ip(&s_, s, slen); EG(ret, err); 1982*f0865ec9SKyle Evans /* m = RSAVP1 ((n, e), s) */ 1983*f0865ec9SKyle Evans ret = rsavp1(pub, &s_, &m_); EG(ret, err); 1984*f0865ec9SKyle Evans /* EM = I2OSP (m, k) */ 1985*f0865ec9SKyle Evans MUST_HAVE((slen <= sizeof(X)), ret, err); 1986*f0865ec9SKyle Evans ret = rsa_i2osp(&m_, X, slen); EG(ret, err); 1987*f0865ec9SKyle Evans 1988*f0865ec9SKyle Evans /* Split the message in B || m1 || H || E with 1989*f0865ec9SKyle Evans * B = '6A', E = 'BC', and H the hash value */ 1990*f0865ec9SKyle Evans if(m1len != NULL){ 1991*f0865ec9SKyle Evans MUST_HAVE((*m1len) >= m1len_, ret, err); 1992*f0865ec9SKyle Evans (*m1len) = m1len_; 1993*f0865ec9SKyle Evans } 1994*f0865ec9SKyle Evans if((X[0] != 0x6a) || (X[slen - 1] != 0xbc)){ 1995*f0865ec9SKyle Evans ret = -1; 1996*f0865ec9SKyle Evans goto err; 1997*f0865ec9SKyle Evans } 1998*f0865ec9SKyle Evans 1999*f0865ec9SKyle Evans /* Compute the hash of m1 || m2 */ 2000*f0865ec9SKyle Evans ret = gen_hash_init(&hctx, gen_hash_type); EG(ret, err); 2001*f0865ec9SKyle Evans ret = gen_hash_update(&hctx, &X[1], m1len_, gen_hash_type); EG(ret, err); 2002*f0865ec9SKyle Evans ret = gen_hash_update(&hctx, m2, m2len, gen_hash_type); EG(ret, err); 2003*f0865ec9SKyle Evans ret = gen_hash_final(&hctx, H, gen_hash_type); EG(ret, err); 2004*f0865ec9SKyle Evans 2005*f0865ec9SKyle Evans /* Compare */ 2006*f0865ec9SKyle Evans ret = are_equal(H, &X[1 + m1len_], (u16)hlen, &cmp); EG(ret, err); 2007*f0865ec9SKyle Evans if(!cmp){ 2008*f0865ec9SKyle Evans ret = -1; 2009*f0865ec9SKyle Evans } 2010*f0865ec9SKyle Evans /* If comparison is OK, copy data */ 2011*f0865ec9SKyle Evans if(m1 != NULL){ 2012*f0865ec9SKyle Evans MUST_HAVE((m1len != NULL), ret, err); 2013*f0865ec9SKyle Evans ret = local_memcpy(m1, &X[1], (*m1len)); EG(ret, err); 2014*f0865ec9SKyle Evans } 2015*f0865ec9SKyle Evans 2016*f0865ec9SKyle Evans err: 2017*f0865ec9SKyle Evans nn_uninit(&m_); 2018*f0865ec9SKyle Evans nn_uninit(&s_); 2019*f0865ec9SKyle Evans 2020*f0865ec9SKyle Evans if(ret && (m1len != 0)){ 2021*f0865ec9SKyle Evans (*m1len) = 0; 2022*f0865ec9SKyle Evans } 2023*f0865ec9SKyle Evans 2024*f0865ec9SKyle Evans return ret; 2025*f0865ec9SKyle Evans } 2026*f0865ec9SKyle Evans 2027*f0865ec9SKyle Evans #ifdef RSA 2028*f0865ec9SKyle Evans /* RSA PKCS#1 test vectors taken from: 2029*f0865ec9SKyle Evans * https://github.com/bdauvergne/python-pkcs1/tree/master/tests/data 2030*f0865ec9SKyle Evans */ 2031*f0865ec9SKyle Evans #include "rsa_pkcs1_tests.h" 2032*f0865ec9SKyle Evans 2033*f0865ec9SKyle Evans int main(int argc, char *argv[]) 2034*f0865ec9SKyle Evans { 2035*f0865ec9SKyle Evans int ret = 0; 2036*f0865ec9SKyle Evans FORCE_USED_VAR(argc); 2037*f0865ec9SKyle Evans FORCE_USED_VAR(argv); 2038*f0865ec9SKyle Evans 2039*f0865ec9SKyle Evans /* Sanity check on size for RSA. 2040*f0865ec9SKyle Evans * NOTE: the double parentheses are here to handle -Wunreachable-code 2041*f0865ec9SKyle Evans */ 2042*f0865ec9SKyle Evans if((NN_USABLE_MAX_BIT_LEN) < (4096)){ 2043*f0865ec9SKyle Evans ext_printf("Error: you seem to have compiled libecc with usable NN size < 4096, not suitable for RSA.\n"); 2044*f0865ec9SKyle Evans ext_printf(" => Please recompile libecc with EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\"\n"); 2045*f0865ec9SKyle Evans ext_printf(" This will increase usable NN for proper RSA up to 4096 bits.\n"); 2046*f0865ec9SKyle Evans ext_printf(" Then recompile the current examples with the same EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\" flag and execute again!\n"); 2047*f0865ec9SKyle Evans /* NOTE: ret = 0 here to pass self tests even if the library is not compatible */ 2048*f0865ec9SKyle Evans ret = 0; 2049*f0865ec9SKyle Evans goto err; 2050*f0865ec9SKyle Evans } 2051*f0865ec9SKyle Evans 2052*f0865ec9SKyle Evans ret = perform_rsa_tests(all_rsa_tests, sizeof(all_rsa_tests) / sizeof(rsa_test*)); 2053*f0865ec9SKyle Evans 2054*f0865ec9SKyle Evans err: 2055*f0865ec9SKyle Evans return ret; 2056*f0865ec9SKyle Evans } 2057*f0865ec9SKyle Evans #endif 2058