1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * The RSA public-key cryptosystem 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6817466cbSJens Wiklander */ 73d3b0591SJens Wiklander 8817466cbSJens Wiklander /* 9817466cbSJens Wiklander * The following sources were referenced in the design of this implementation 10817466cbSJens Wiklander * of the RSA algorithm: 11817466cbSJens Wiklander * 12817466cbSJens Wiklander * [1] A method for obtaining digital signatures and public-key cryptosystems 13817466cbSJens Wiklander * R Rivest, A Shamir, and L Adleman 14817466cbSJens Wiklander * http://people.csail.mit.edu/rivest/pubs.html#RSA78 15817466cbSJens Wiklander * 16817466cbSJens Wiklander * [2] Handbook of Applied Cryptography - 1997, Chapter 8 17817466cbSJens Wiklander * Menezes, van Oorschot and Vanstone 18817466cbSJens Wiklander * 19817466cbSJens Wiklander * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks 20817466cbSJens Wiklander * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and 21817466cbSJens Wiklander * Stefan Mangard 22817466cbSJens Wiklander * https://arxiv.org/abs/1702.08719v2 23817466cbSJens Wiklander * 24817466cbSJens Wiklander */ 25817466cbSJens Wiklander 267901324dSJerome Forissier #include "common.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 29817466cbSJens Wiklander 30817466cbSJens Wiklander #include "mbedtls/rsa.h" 31*b0563631STom Van Eyck #include "bignum_core.h" 3232b31808SJens Wiklander #include "rsa_alt_helpers.h" 33*b0563631STom Van Eyck #include "rsa_internal.h" 34817466cbSJens Wiklander #include "mbedtls/oid.h" 35*b0563631STom Van Eyck #include "mbedtls/asn1write.h" 363d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 3711fa71b9SJerome Forissier #include "mbedtls/error.h" 38039e02dfSJerome Forissier #include "constant_time_internal.h" 39039e02dfSJerome Forissier #include "mbedtls/constant_time.h" 40*b0563631STom Van Eyck #include "md_psa.h" 41817466cbSJens Wiklander 42817466cbSJens Wiklander #include <string.h> 43817466cbSJens Wiklander 447901324dSJerome Forissier #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__) 45817466cbSJens Wiklander #include <stdlib.h> 46817466cbSJens Wiklander #endif 47817466cbSJens Wiklander 48817466cbSJens Wiklander #include "mbedtls/platform.h" 49817466cbSJens Wiklander 50a846630fSJens Wiklander #include <fault_mitigation.h> 51a846630fSJens Wiklander 52*b0563631STom Van Eyck /* 53*b0563631STom Van Eyck * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. 54*b0563631STom Van Eyck * 55*b0563631STom Van Eyck * The value zero is: 56*b0563631STom Van Eyck * - never a valid value for an RSA parameter 57*b0563631STom Van Eyck * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). 58*b0563631STom Van Eyck * 59*b0563631STom Van Eyck * Since values can't be omitted in PKCS#1, passing a zero value to 60*b0563631STom Van Eyck * rsa_complete() would be incorrect, so reject zero values early. 61*b0563631STom Van Eyck */ 62*b0563631STom Van Eyck static int asn1_get_nonzero_mpi(unsigned char **p, 63*b0563631STom Van Eyck const unsigned char *end, 64*b0563631STom Van Eyck mbedtls_mpi *X) 65*b0563631STom Van Eyck { 66*b0563631STom Van Eyck int ret; 67*b0563631STom Van Eyck 68*b0563631STom Van Eyck ret = mbedtls_asn1_get_mpi(p, end, X); 69*b0563631STom Van Eyck if (ret != 0) { 70*b0563631STom Van Eyck return ret; 71*b0563631STom Van Eyck } 72*b0563631STom Van Eyck 73*b0563631STom Van Eyck if (mbedtls_mpi_cmp_int(X, 0) == 0) { 74*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 75*b0563631STom Van Eyck } 76*b0563631STom Van Eyck 77*b0563631STom Van Eyck return 0; 78*b0563631STom Van Eyck } 79*b0563631STom Van Eyck 80*b0563631STom Van Eyck int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen) 81*b0563631STom Van Eyck { 82*b0563631STom Van Eyck int ret, version; 83*b0563631STom Van Eyck size_t len; 84*b0563631STom Van Eyck unsigned char *p, *end; 85*b0563631STom Van Eyck 86*b0563631STom Van Eyck mbedtls_mpi T; 87*b0563631STom Van Eyck mbedtls_mpi_init(&T); 88*b0563631STom Van Eyck 89*b0563631STom Van Eyck p = (unsigned char *) key; 90*b0563631STom Van Eyck end = p + keylen; 91*b0563631STom Van Eyck 92*b0563631STom Van Eyck /* 93*b0563631STom Van Eyck * This function parses the RSAPrivateKey (PKCS#1) 94*b0563631STom Van Eyck * 95*b0563631STom Van Eyck * RSAPrivateKey ::= SEQUENCE { 96*b0563631STom Van Eyck * version Version, 97*b0563631STom Van Eyck * modulus INTEGER, -- n 98*b0563631STom Van Eyck * publicExponent INTEGER, -- e 99*b0563631STom Van Eyck * privateExponent INTEGER, -- d 100*b0563631STom Van Eyck * prime1 INTEGER, -- p 101*b0563631STom Van Eyck * prime2 INTEGER, -- q 102*b0563631STom Van Eyck * exponent1 INTEGER, -- d mod (p-1) 103*b0563631STom Van Eyck * exponent2 INTEGER, -- d mod (q-1) 104*b0563631STom Van Eyck * coefficient INTEGER, -- (inverse of q) mod p 105*b0563631STom Van Eyck * otherPrimeInfos OtherPrimeInfos OPTIONAL 106*b0563631STom Van Eyck * } 107*b0563631STom Van Eyck */ 108*b0563631STom Van Eyck if ((ret = mbedtls_asn1_get_tag(&p, end, &len, 109*b0563631STom Van Eyck MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 110*b0563631STom Van Eyck return ret; 111*b0563631STom Van Eyck } 112*b0563631STom Van Eyck 113*b0563631STom Van Eyck if (end != p + len) { 114*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 115*b0563631STom Van Eyck } 116*b0563631STom Van Eyck 117*b0563631STom Van Eyck if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { 118*b0563631STom Van Eyck return ret; 119*b0563631STom Van Eyck } 120*b0563631STom Van Eyck 121*b0563631STom Van Eyck if (version != 0) { 122*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 123*b0563631STom Van Eyck } 124*b0563631STom Van Eyck 125*b0563631STom Van Eyck /* Import N */ 126*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 127*b0563631STom Van Eyck (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL, 128*b0563631STom Van Eyck NULL, NULL)) != 0) { 129*b0563631STom Van Eyck goto cleanup; 130*b0563631STom Van Eyck } 131*b0563631STom Van Eyck 132*b0563631STom Van Eyck /* Import E */ 133*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 134*b0563631STom Van Eyck (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, 135*b0563631STom Van Eyck NULL, &T)) != 0) { 136*b0563631STom Van Eyck goto cleanup; 137*b0563631STom Van Eyck } 138*b0563631STom Van Eyck 139*b0563631STom Van Eyck /* Import D */ 140*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 141*b0563631STom Van Eyck (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, 142*b0563631STom Van Eyck &T, NULL)) != 0) { 143*b0563631STom Van Eyck goto cleanup; 144*b0563631STom Van Eyck } 145*b0563631STom Van Eyck 146*b0563631STom Van Eyck /* Import P */ 147*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 148*b0563631STom Van Eyck (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL, 149*b0563631STom Van Eyck NULL, NULL)) != 0) { 150*b0563631STom Van Eyck goto cleanup; 151*b0563631STom Van Eyck } 152*b0563631STom Van Eyck 153*b0563631STom Van Eyck /* Import Q */ 154*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 155*b0563631STom Van Eyck (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T, 156*b0563631STom Van Eyck NULL, NULL)) != 0) { 157*b0563631STom Van Eyck goto cleanup; 158*b0563631STom Van Eyck } 159*b0563631STom Van Eyck 160*b0563631STom Van Eyck #if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) 161*b0563631STom Van Eyck /* 162*b0563631STom Van Eyck * The RSA CRT parameters DP, DQ and QP are nominally redundant, in 163*b0563631STom Van Eyck * that they can be easily recomputed from D, P and Q. However by 164*b0563631STom Van Eyck * parsing them from the PKCS1 structure it is possible to avoid 165*b0563631STom Van Eyck * recalculating them which both reduces the overhead of loading 166*b0563631STom Van Eyck * RSA private keys into memory and also avoids side channels which 167*b0563631STom Van Eyck * can arise when computing those values, since all of D, P, and Q 168*b0563631STom Van Eyck * are secret. See https://eprint.iacr.org/2020/055 for a 169*b0563631STom Van Eyck * description of one such attack. 170*b0563631STom Van Eyck */ 171*b0563631STom Van Eyck 172*b0563631STom Van Eyck /* Import DP */ 173*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 174*b0563631STom Van Eyck (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) { 175*b0563631STom Van Eyck goto cleanup; 176*b0563631STom Van Eyck } 177*b0563631STom Van Eyck 178*b0563631STom Van Eyck /* Import DQ */ 179*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 180*b0563631STom Van Eyck (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) { 181*b0563631STom Van Eyck goto cleanup; 182*b0563631STom Van Eyck } 183*b0563631STom Van Eyck 184*b0563631STom Van Eyck /* Import QP */ 185*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 186*b0563631STom Van Eyck (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) { 187*b0563631STom Van Eyck goto cleanup; 188*b0563631STom Van Eyck } 189*b0563631STom Van Eyck 190*b0563631STom Van Eyck #else 191*b0563631STom Van Eyck /* Verify existence of the CRT params */ 192*b0563631STom Van Eyck if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 193*b0563631STom Van Eyck (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || 194*b0563631STom Van Eyck (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) { 195*b0563631STom Van Eyck goto cleanup; 196*b0563631STom Van Eyck } 197*b0563631STom Van Eyck #endif 198*b0563631STom Van Eyck 199*b0563631STom Van Eyck /* rsa_complete() doesn't complete anything with the default 200*b0563631STom Van Eyck * implementation but is still called: 201*b0563631STom Van Eyck * - for the benefit of alternative implementation that may want to 202*b0563631STom Van Eyck * pre-compute stuff beyond what's provided (eg Montgomery factors) 203*b0563631STom Van Eyck * - as is also sanity-checks the key 204*b0563631STom Van Eyck * 205*b0563631STom Van Eyck * Furthermore, we also check the public part for consistency with 206*b0563631STom Van Eyck * mbedtls_pk_parse_pubkey(), as it includes size minima for example. 207*b0563631STom Van Eyck */ 208*b0563631STom Van Eyck if ((ret = mbedtls_rsa_complete(rsa)) != 0 || 209*b0563631STom Van Eyck (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) { 210*b0563631STom Van Eyck goto cleanup; 211*b0563631STom Van Eyck } 212*b0563631STom Van Eyck 213*b0563631STom Van Eyck if (p != end) { 214*b0563631STom Van Eyck ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 215*b0563631STom Van Eyck } 216*b0563631STom Van Eyck 217*b0563631STom Van Eyck cleanup: 218*b0563631STom Van Eyck 219*b0563631STom Van Eyck mbedtls_mpi_free(&T); 220*b0563631STom Van Eyck 221*b0563631STom Van Eyck if (ret != 0) { 222*b0563631STom Van Eyck mbedtls_rsa_free(rsa); 223*b0563631STom Van Eyck } 224*b0563631STom Van Eyck 225*b0563631STom Van Eyck return ret; 226*b0563631STom Van Eyck } 227*b0563631STom Van Eyck 228*b0563631STom Van Eyck int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen) 229*b0563631STom Van Eyck { 230*b0563631STom Van Eyck unsigned char *p = (unsigned char *) key; 231*b0563631STom Van Eyck unsigned char *end = (unsigned char *) (key + keylen); 232*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 233*b0563631STom Van Eyck size_t len; 234*b0563631STom Van Eyck 235*b0563631STom Van Eyck /* 236*b0563631STom Van Eyck * RSAPublicKey ::= SEQUENCE { 237*b0563631STom Van Eyck * modulus INTEGER, -- n 238*b0563631STom Van Eyck * publicExponent INTEGER -- e 239*b0563631STom Van Eyck * } 240*b0563631STom Van Eyck */ 241*b0563631STom Van Eyck 242*b0563631STom Van Eyck if ((ret = mbedtls_asn1_get_tag(&p, end, &len, 243*b0563631STom Van Eyck MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 244*b0563631STom Van Eyck return ret; 245*b0563631STom Van Eyck } 246*b0563631STom Van Eyck 247*b0563631STom Van Eyck if (end != p + len) { 248*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 249*b0563631STom Van Eyck } 250*b0563631STom Van Eyck 251*b0563631STom Van Eyck /* Import N */ 252*b0563631STom Van Eyck if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { 253*b0563631STom Van Eyck return ret; 254*b0563631STom Van Eyck } 255*b0563631STom Van Eyck 256*b0563631STom Van Eyck if ((ret = mbedtls_rsa_import_raw(rsa, p, len, NULL, 0, NULL, 0, 257*b0563631STom Van Eyck NULL, 0, NULL, 0)) != 0) { 258*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 259*b0563631STom Van Eyck } 260*b0563631STom Van Eyck 261*b0563631STom Van Eyck p += len; 262*b0563631STom Van Eyck 263*b0563631STom Van Eyck /* Import E */ 264*b0563631STom Van Eyck if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { 265*b0563631STom Van Eyck return ret; 266*b0563631STom Van Eyck } 267*b0563631STom Van Eyck 268*b0563631STom Van Eyck if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0, 269*b0563631STom Van Eyck NULL, 0, p, len)) != 0) { 270*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 271*b0563631STom Van Eyck } 272*b0563631STom Van Eyck 273*b0563631STom Van Eyck p += len; 274*b0563631STom Van Eyck 275*b0563631STom Van Eyck if (mbedtls_rsa_complete(rsa) != 0 || 276*b0563631STom Van Eyck mbedtls_rsa_check_pubkey(rsa) != 0) { 277*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 278*b0563631STom Van Eyck } 279*b0563631STom Van Eyck 280*b0563631STom Van Eyck if (p != end) { 281*b0563631STom Van Eyck return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 282*b0563631STom Van Eyck } 283*b0563631STom Van Eyck 284*b0563631STom Van Eyck return 0; 285*b0563631STom Van Eyck } 286*b0563631STom Van Eyck 287*b0563631STom Van Eyck int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start, 288*b0563631STom Van Eyck unsigned char **p) 289*b0563631STom Van Eyck { 290*b0563631STom Van Eyck size_t len = 0; 291*b0563631STom Van Eyck int ret; 292*b0563631STom Van Eyck 293*b0563631STom Van Eyck mbedtls_mpi T; /* Temporary holding the exported parameters */ 294*b0563631STom Van Eyck 295*b0563631STom Van Eyck /* 296*b0563631STom Van Eyck * Export the parameters one after another to avoid simultaneous copies. 297*b0563631STom Van Eyck */ 298*b0563631STom Van Eyck 299*b0563631STom Van Eyck mbedtls_mpi_init(&T); 300*b0563631STom Van Eyck 301*b0563631STom Van Eyck /* Export QP */ 302*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 || 303*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 304*b0563631STom Van Eyck goto end_of_export; 305*b0563631STom Van Eyck } 306*b0563631STom Van Eyck len += ret; 307*b0563631STom Van Eyck 308*b0563631STom Van Eyck /* Export DQ */ 309*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 || 310*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 311*b0563631STom Van Eyck goto end_of_export; 312*b0563631STom Van Eyck } 313*b0563631STom Van Eyck len += ret; 314*b0563631STom Van Eyck 315*b0563631STom Van Eyck /* Export DP */ 316*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 || 317*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 318*b0563631STom Van Eyck goto end_of_export; 319*b0563631STom Van Eyck } 320*b0563631STom Van Eyck len += ret; 321*b0563631STom Van Eyck 322*b0563631STom Van Eyck /* Export Q */ 323*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, &T, NULL, NULL)) != 0 || 324*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 325*b0563631STom Van Eyck goto end_of_export; 326*b0563631STom Van Eyck } 327*b0563631STom Van Eyck len += ret; 328*b0563631STom Van Eyck 329*b0563631STom Van Eyck /* Export P */ 330*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, NULL, &T, NULL, NULL, NULL)) != 0 || 331*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 332*b0563631STom Van Eyck goto end_of_export; 333*b0563631STom Van Eyck } 334*b0563631STom Van Eyck len += ret; 335*b0563631STom Van Eyck 336*b0563631STom Van Eyck /* Export D */ 337*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, &T, NULL)) != 0 || 338*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 339*b0563631STom Van Eyck goto end_of_export; 340*b0563631STom Van Eyck } 341*b0563631STom Van Eyck len += ret; 342*b0563631STom Van Eyck 343*b0563631STom Van Eyck /* Export E */ 344*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 || 345*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 346*b0563631STom Van Eyck goto end_of_export; 347*b0563631STom Van Eyck } 348*b0563631STom Van Eyck len += ret; 349*b0563631STom Van Eyck 350*b0563631STom Van Eyck /* Export N */ 351*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 || 352*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 353*b0563631STom Van Eyck goto end_of_export; 354*b0563631STom Van Eyck } 355*b0563631STom Van Eyck len += ret; 356*b0563631STom Van Eyck 357*b0563631STom Van Eyck end_of_export: 358*b0563631STom Van Eyck 359*b0563631STom Van Eyck mbedtls_mpi_free(&T); 360*b0563631STom Van Eyck if (ret < 0) { 361*b0563631STom Van Eyck return ret; 362*b0563631STom Van Eyck } 363*b0563631STom Van Eyck 364*b0563631STom Van Eyck MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, start, 0)); 365*b0563631STom Van Eyck MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 366*b0563631STom Van Eyck MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 367*b0563631STom Van Eyck MBEDTLS_ASN1_CONSTRUCTED | 368*b0563631STom Van Eyck MBEDTLS_ASN1_SEQUENCE)); 369*b0563631STom Van Eyck 370*b0563631STom Van Eyck return (int) len; 371*b0563631STom Van Eyck } 372*b0563631STom Van Eyck 373*b0563631STom Van Eyck /* 374*b0563631STom Van Eyck * RSAPublicKey ::= SEQUENCE { 375*b0563631STom Van Eyck * modulus INTEGER, -- n 376*b0563631STom Van Eyck * publicExponent INTEGER -- e 377*b0563631STom Van Eyck * } 378*b0563631STom Van Eyck */ 379*b0563631STom Van Eyck int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start, 380*b0563631STom Van Eyck unsigned char **p) 381*b0563631STom Van Eyck { 382*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 383*b0563631STom Van Eyck size_t len = 0; 384*b0563631STom Van Eyck mbedtls_mpi T; 385*b0563631STom Van Eyck 386*b0563631STom Van Eyck mbedtls_mpi_init(&T); 387*b0563631STom Van Eyck 388*b0563631STom Van Eyck /* Export E */ 389*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 || 390*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 391*b0563631STom Van Eyck goto end_of_export; 392*b0563631STom Van Eyck } 393*b0563631STom Van Eyck len += ret; 394*b0563631STom Van Eyck 395*b0563631STom Van Eyck /* Export N */ 396*b0563631STom Van Eyck if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 || 397*b0563631STom Van Eyck (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { 398*b0563631STom Van Eyck goto end_of_export; 399*b0563631STom Van Eyck } 400*b0563631STom Van Eyck len += ret; 401*b0563631STom Van Eyck 402*b0563631STom Van Eyck end_of_export: 403*b0563631STom Van Eyck 404*b0563631STom Van Eyck mbedtls_mpi_free(&T); 405*b0563631STom Van Eyck if (ret < 0) { 406*b0563631STom Van Eyck return ret; 407*b0563631STom Van Eyck } 408*b0563631STom Van Eyck 409*b0563631STom Van Eyck MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 410*b0563631STom Van Eyck MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | 411*b0563631STom Van Eyck MBEDTLS_ASN1_SEQUENCE)); 412*b0563631STom Van Eyck 413*b0563631STom Van Eyck return (int) len; 414*b0563631STom Van Eyck } 415*b0563631STom Van Eyck 416*b0563631STom Van Eyck #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) 417*b0563631STom Van Eyck 418*b0563631STom Van Eyck /** This function performs the unpadding part of a PKCS#1 v1.5 decryption 419*b0563631STom Van Eyck * operation (EME-PKCS1-v1_5 decoding). 420*b0563631STom Van Eyck * 421*b0563631STom Van Eyck * \note The return value from this function is a sensitive value 422*b0563631STom Van Eyck * (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen 423*b0563631STom Van Eyck * in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING 424*b0563631STom Van Eyck * is often a situation that an attacker can provoke and leaking which 425*b0563631STom Van Eyck * one is the result is precisely the information the attacker wants. 426*b0563631STom Van Eyck * 427*b0563631STom Van Eyck * \param input The input buffer which is the payload inside PKCS#1v1.5 428*b0563631STom Van Eyck * encryption padding, called the "encoded message EM" 429*b0563631STom Van Eyck * by the terminology. 430*b0563631STom Van Eyck * \param ilen The length of the payload in the \p input buffer. 431*b0563631STom Van Eyck * \param output The buffer for the payload, called "message M" by the 432*b0563631STom Van Eyck * PKCS#1 terminology. This must be a writable buffer of 433*b0563631STom Van Eyck * length \p output_max_len bytes. 434*b0563631STom Van Eyck * \param olen The address at which to store the length of 435*b0563631STom Van Eyck * the payload. This must not be \c NULL. 436*b0563631STom Van Eyck * \param output_max_len The length in bytes of the output buffer \p output. 437*b0563631STom Van Eyck * 438*b0563631STom Van Eyck * \return \c 0 on success. 439*b0563631STom Van Eyck * \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE 440*b0563631STom Van Eyck * The output buffer is too small for the unpadded payload. 441*b0563631STom Van Eyck * \return #MBEDTLS_ERR_RSA_INVALID_PADDING 442*b0563631STom Van Eyck * The input doesn't contain properly formatted padding. 443*b0563631STom Van Eyck */ 444*b0563631STom Van Eyck static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input, 445*b0563631STom Van Eyck size_t ilen, 446*b0563631STom Van Eyck unsigned char *output, 447*b0563631STom Van Eyck size_t output_max_len, 448*b0563631STom Van Eyck size_t *olen) 449*b0563631STom Van Eyck { 450*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 451*b0563631STom Van Eyck size_t i, plaintext_max_size; 452*b0563631STom Van Eyck 453*b0563631STom Van Eyck /* The following variables take sensitive values: their value must 454*b0563631STom Van Eyck * not leak into the observable behavior of the function other than 455*b0563631STom Van Eyck * the designated outputs (output, olen, return value). Otherwise 456*b0563631STom Van Eyck * this would open the execution of the function to 457*b0563631STom Van Eyck * side-channel-based variants of the Bleichenbacher padding oracle 458*b0563631STom Van Eyck * attack. Potential side channels include overall timing, memory 459*b0563631STom Van Eyck * access patterns (especially visible to an adversary who has access 460*b0563631STom Van Eyck * to a shared memory cache), and branches (especially visible to 461*b0563631STom Van Eyck * an adversary who has access to a shared code cache or to a shared 462*b0563631STom Van Eyck * branch predictor). */ 463*b0563631STom Van Eyck size_t pad_count = 0; 464*b0563631STom Van Eyck mbedtls_ct_condition_t bad; 465*b0563631STom Van Eyck mbedtls_ct_condition_t pad_done; 466*b0563631STom Van Eyck size_t plaintext_size = 0; 467*b0563631STom Van Eyck mbedtls_ct_condition_t output_too_large; 468*b0563631STom Van Eyck 469*b0563631STom Van Eyck plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11 470*b0563631STom Van Eyck : output_max_len; 471*b0563631STom Van Eyck 472*b0563631STom Van Eyck /* Check and get padding length in constant time and constant 473*b0563631STom Van Eyck * memory trace. The first byte must be 0. */ 474*b0563631STom Van Eyck bad = mbedtls_ct_bool(input[0]); 475*b0563631STom Van Eyck 476*b0563631STom Van Eyck 477*b0563631STom Van Eyck /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00 478*b0563631STom Van Eyck * where PS must be at least 8 nonzero bytes. */ 479*b0563631STom Van Eyck bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(input[1], MBEDTLS_RSA_CRYPT)); 480*b0563631STom Van Eyck 481*b0563631STom Van Eyck /* Read the whole buffer. Set pad_done to nonzero if we find 482*b0563631STom Van Eyck * the 0x00 byte and remember the padding length in pad_count. */ 483*b0563631STom Van Eyck pad_done = MBEDTLS_CT_FALSE; 484*b0563631STom Van Eyck for (i = 2; i < ilen; i++) { 485*b0563631STom Van Eyck mbedtls_ct_condition_t found = mbedtls_ct_uint_eq(input[i], 0); 486*b0563631STom Van Eyck pad_done = mbedtls_ct_bool_or(pad_done, found); 487*b0563631STom Van Eyck pad_count += mbedtls_ct_uint_if_else_0(mbedtls_ct_bool_not(pad_done), 1); 488*b0563631STom Van Eyck } 489*b0563631STom Van Eyck 490*b0563631STom Van Eyck /* If pad_done is still zero, there's no data, only unfinished padding. */ 491*b0563631STom Van Eyck bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_not(pad_done)); 492*b0563631STom Van Eyck 493*b0563631STom Van Eyck /* There must be at least 8 bytes of padding. */ 494*b0563631STom Van Eyck bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_gt(8, pad_count)); 495*b0563631STom Van Eyck 496*b0563631STom Van Eyck /* If the padding is valid, set plaintext_size to the number of 497*b0563631STom Van Eyck * remaining bytes after stripping the padding. If the padding 498*b0563631STom Van Eyck * is invalid, avoid leaking this fact through the size of the 499*b0563631STom Van Eyck * output: use the maximum message size that fits in the output 500*b0563631STom Van Eyck * buffer. Do it without branches to avoid leaking the padding 501*b0563631STom Van Eyck * validity through timing. RSA keys are small enough that all the 502*b0563631STom Van Eyck * size_t values involved fit in unsigned int. */ 503*b0563631STom Van Eyck plaintext_size = mbedtls_ct_uint_if( 504*b0563631STom Van Eyck bad, (unsigned) plaintext_max_size, 505*b0563631STom Van Eyck (unsigned) (ilen - pad_count - 3)); 506*b0563631STom Van Eyck 507*b0563631STom Van Eyck /* Set output_too_large to 0 if the plaintext fits in the output 508*b0563631STom Van Eyck * buffer and to 1 otherwise. */ 509*b0563631STom Van Eyck output_too_large = mbedtls_ct_uint_gt(plaintext_size, 510*b0563631STom Van Eyck plaintext_max_size); 511*b0563631STom Van Eyck 512*b0563631STom Van Eyck /* Set ret without branches to avoid timing attacks. Return: 513*b0563631STom Van Eyck * - INVALID_PADDING if the padding is bad (bad != 0). 514*b0563631STom Van Eyck * - OUTPUT_TOO_LARGE if the padding is good but the decrypted 515*b0563631STom Van Eyck * plaintext does not fit in the output buffer. 516*b0563631STom Van Eyck * - 0 if the padding is correct. */ 517*b0563631STom Van Eyck ret = mbedtls_ct_error_if( 518*b0563631STom Van Eyck bad, 519*b0563631STom Van Eyck MBEDTLS_ERR_RSA_INVALID_PADDING, 520*b0563631STom Van Eyck mbedtls_ct_error_if_else_0(output_too_large, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) 521*b0563631STom Van Eyck ); 522*b0563631STom Van Eyck 523*b0563631STom Van Eyck /* If the padding is bad or the plaintext is too large, zero the 524*b0563631STom Van Eyck * data that we're about to copy to the output buffer. 525*b0563631STom Van Eyck * We need to copy the same amount of data 526*b0563631STom Van Eyck * from the same buffer whether the padding is good or not to 527*b0563631STom Van Eyck * avoid leaking the padding validity through overall timing or 528*b0563631STom Van Eyck * through memory or cache access patterns. */ 529*b0563631STom Van Eyck mbedtls_ct_zeroize_if(mbedtls_ct_bool_or(bad, output_too_large), input + 11, ilen - 11); 530*b0563631STom Van Eyck 531*b0563631STom Van Eyck /* If the plaintext is too large, truncate it to the buffer size. 532*b0563631STom Van Eyck * Copy anyway to avoid revealing the length through timing, because 533*b0563631STom Van Eyck * revealing the length is as bad as revealing the padding validity 534*b0563631STom Van Eyck * for a Bleichenbacher attack. */ 535*b0563631STom Van Eyck plaintext_size = mbedtls_ct_uint_if(output_too_large, 536*b0563631STom Van Eyck (unsigned) plaintext_max_size, 537*b0563631STom Van Eyck (unsigned) plaintext_size); 538*b0563631STom Van Eyck 539*b0563631STom Van Eyck /* Move the plaintext to the leftmost position where it can start in 540*b0563631STom Van Eyck * the working buffer, i.e. make it start plaintext_max_size from 541*b0563631STom Van Eyck * the end of the buffer. Do this with a memory access trace that 542*b0563631STom Van Eyck * does not depend on the plaintext size. After this move, the 543*b0563631STom Van Eyck * starting location of the plaintext is no longer sensitive 544*b0563631STom Van Eyck * information. */ 545*b0563631STom Van Eyck mbedtls_ct_memmove_left(input + ilen - plaintext_max_size, 546*b0563631STom Van Eyck plaintext_max_size, 547*b0563631STom Van Eyck plaintext_max_size - plaintext_size); 548*b0563631STom Van Eyck 549*b0563631STom Van Eyck /* Finally copy the decrypted plaintext plus trailing zeros into the output 550*b0563631STom Van Eyck * buffer. If output_max_len is 0, then output may be an invalid pointer 551*b0563631STom Van Eyck * and the result of memcpy() would be undefined; prevent undefined 552*b0563631STom Van Eyck * behavior making sure to depend only on output_max_len (the size of the 553*b0563631STom Van Eyck * user-provided output buffer), which is independent from plaintext 554*b0563631STom Van Eyck * length, validity of padding, success of the decryption, and other 555*b0563631STom Van Eyck * secrets. */ 556*b0563631STom Van Eyck if (output_max_len != 0) { 557*b0563631STom Van Eyck memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size); 558*b0563631STom Van Eyck } 559*b0563631STom Van Eyck 560*b0563631STom Van Eyck /* Report the amount of data we copied to the output buffer. In case 561*b0563631STom Van Eyck * of errors (bad padding or output too large), the value of *olen 562*b0563631STom Van Eyck * when this function returns is not specified. Making it equivalent 563*b0563631STom Van Eyck * to the good case limits the risks of leaking the padding validity. */ 564*b0563631STom Van Eyck *olen = plaintext_size; 565*b0563631STom Van Eyck 566*b0563631STom Van Eyck return ret; 567*b0563631STom Van Eyck } 568*b0563631STom Van Eyck 569*b0563631STom Van Eyck #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ 570*b0563631STom Van Eyck 5713d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_ALT) 5723d3b0591SJens Wiklander 5733d3b0591SJens Wiklander int mbedtls_rsa_import(mbedtls_rsa_context *ctx, 5743d3b0591SJens Wiklander const mbedtls_mpi *N, 5753d3b0591SJens Wiklander const mbedtls_mpi *P, const mbedtls_mpi *Q, 5763d3b0591SJens Wiklander const mbedtls_mpi *D, const mbedtls_mpi *E) 5773d3b0591SJens Wiklander { 57811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 5793d3b0591SJens Wiklander 5803d3b0591SJens Wiklander if ((N != NULL && (ret = mbedtls_mpi_copy(&ctx->N, N)) != 0) || 5813d3b0591SJens Wiklander (P != NULL && (ret = mbedtls_mpi_copy(&ctx->P, P)) != 0) || 5823d3b0591SJens Wiklander (Q != NULL && (ret = mbedtls_mpi_copy(&ctx->Q, Q)) != 0) || 5833d3b0591SJens Wiklander (D != NULL && (ret = mbedtls_mpi_copy(&ctx->D, D)) != 0) || 58432b31808SJens Wiklander (E != NULL && (ret = mbedtls_mpi_copy(&ctx->E, E)) != 0)) { 58532b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 5863d3b0591SJens Wiklander } 5873d3b0591SJens Wiklander 58832b31808SJens Wiklander if (N != NULL) { 5893d3b0591SJens Wiklander ctx->len = mbedtls_mpi_size(&ctx->N); 59032b31808SJens Wiklander } 5913d3b0591SJens Wiklander 59232b31808SJens Wiklander return 0; 5933d3b0591SJens Wiklander } 5943d3b0591SJens Wiklander 5953d3b0591SJens Wiklander int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx, 5963d3b0591SJens Wiklander unsigned char const *N, size_t N_len, 5973d3b0591SJens Wiklander unsigned char const *P, size_t P_len, 5983d3b0591SJens Wiklander unsigned char const *Q, size_t Q_len, 5993d3b0591SJens Wiklander unsigned char const *D, size_t D_len, 6003d3b0591SJens Wiklander unsigned char const *E, size_t E_len) 6013d3b0591SJens Wiklander { 6023d3b0591SJens Wiklander int ret = 0; 6033d3b0591SJens Wiklander 60432b31808SJens Wiklander if (N != NULL) { 6053d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->N, N, N_len)); 6063d3b0591SJens Wiklander ctx->len = mbedtls_mpi_size(&ctx->N); 6073d3b0591SJens Wiklander } 6083d3b0591SJens Wiklander 60932b31808SJens Wiklander if (P != NULL) { 6103d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->P, P, P_len)); 61132b31808SJens Wiklander } 6123d3b0591SJens Wiklander 61332b31808SJens Wiklander if (Q != NULL) { 6143d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->Q, Q, Q_len)); 61532b31808SJens Wiklander } 6163d3b0591SJens Wiklander 61732b31808SJens Wiklander if (D != NULL) { 6183d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->D, D, D_len)); 61932b31808SJens Wiklander } 6203d3b0591SJens Wiklander 62132b31808SJens Wiklander if (E != NULL) { 6223d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->E, E, E_len)); 62332b31808SJens Wiklander } 6243d3b0591SJens Wiklander 6253d3b0591SJens Wiklander cleanup: 6263d3b0591SJens Wiklander 62732b31808SJens Wiklander if (ret != 0) { 62832b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 62932b31808SJens Wiklander } 6303d3b0591SJens Wiklander 63132b31808SJens Wiklander return 0; 6323d3b0591SJens Wiklander } 6333d3b0591SJens Wiklander 6343d3b0591SJens Wiklander /* 6353d3b0591SJens Wiklander * Checks whether the context fields are set in such a way 6363d3b0591SJens Wiklander * that the RSA primitives will be able to execute without error. 6373d3b0591SJens Wiklander * It does *not* make guarantees for consistency of the parameters. 6383d3b0591SJens Wiklander */ 6393d3b0591SJens Wiklander static int rsa_check_context(mbedtls_rsa_context const *ctx, int is_priv, 6403d3b0591SJens Wiklander int blinding_needed) 6413d3b0591SJens Wiklander { 6423d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 6433d3b0591SJens Wiklander /* blinding_needed is only used for NO_CRT to decide whether 6443d3b0591SJens Wiklander * P,Q need to be present or not. */ 6453d3b0591SJens Wiklander ((void) blinding_needed); 6463d3b0591SJens Wiklander #endif 6473d3b0591SJens Wiklander 6483d3b0591SJens Wiklander if (ctx->len != mbedtls_mpi_size(&ctx->N) || 64932b31808SJens Wiklander ctx->len > MBEDTLS_MPI_MAX_SIZE) { 65032b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 6513d3b0591SJens Wiklander } 6523d3b0591SJens Wiklander 6533d3b0591SJens Wiklander /* 6543d3b0591SJens Wiklander * 1. Modular exponentiation needs positive, odd moduli. 6553d3b0591SJens Wiklander */ 6563d3b0591SJens Wiklander 6573d3b0591SJens Wiklander /* Modular exponentiation wrt. N is always used for 6583d3b0591SJens Wiklander * RSA public key operations. */ 6593d3b0591SJens Wiklander if (mbedtls_mpi_cmp_int(&ctx->N, 0) <= 0 || 66032b31808SJens Wiklander mbedtls_mpi_get_bit(&ctx->N, 0) == 0) { 66132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 6623d3b0591SJens Wiklander } 6633d3b0591SJens Wiklander 6643d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 6653d3b0591SJens Wiklander /* Modular exponentiation for P and Q is only 6663d3b0591SJens Wiklander * used for private key operations and if CRT 6673d3b0591SJens Wiklander * is used. */ 6683d3b0591SJens Wiklander if (is_priv && 6693d3b0591SJens Wiklander (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 || 6703d3b0591SJens Wiklander mbedtls_mpi_get_bit(&ctx->P, 0) == 0 || 6713d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0 || 67232b31808SJens Wiklander mbedtls_mpi_get_bit(&ctx->Q, 0) == 0)) { 67332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 6743d3b0591SJens Wiklander } 6753d3b0591SJens Wiklander #endif /* !MBEDTLS_RSA_NO_CRT */ 6763d3b0591SJens Wiklander 6773d3b0591SJens Wiklander /* 6783d3b0591SJens Wiklander * 2. Exponents must be positive 6793d3b0591SJens Wiklander */ 6803d3b0591SJens Wiklander 6813d3b0591SJens Wiklander /* Always need E for public key operations */ 68232b31808SJens Wiklander if (mbedtls_mpi_cmp_int(&ctx->E, 0) <= 0) { 68332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 68432b31808SJens Wiklander } 6853d3b0591SJens Wiklander 6863d3b0591SJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 6873d3b0591SJens Wiklander /* For private key operations, use D or DP & DQ 6883d3b0591SJens Wiklander * as (unblinded) exponents. */ 68932b31808SJens Wiklander if (is_priv && mbedtls_mpi_cmp_int(&ctx->D, 0) <= 0) { 69032b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 69132b31808SJens Wiklander } 6923d3b0591SJens Wiklander #else 6933d3b0591SJens Wiklander if (is_priv && 6943d3b0591SJens Wiklander (mbedtls_mpi_cmp_int(&ctx->DP, 0) <= 0 || 69532b31808SJens Wiklander mbedtls_mpi_cmp_int(&ctx->DQ, 0) <= 0)) { 69632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 6973d3b0591SJens Wiklander } 6983d3b0591SJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 6993d3b0591SJens Wiklander 7003d3b0591SJens Wiklander /* Blinding shouldn't make exponents negative either, 7013d3b0591SJens Wiklander * so check that P, Q >= 1 if that hasn't yet been 7023d3b0591SJens Wiklander * done as part of 1. */ 7033d3b0591SJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 7043d3b0591SJens Wiklander if (is_priv && blinding_needed && 7053d3b0591SJens Wiklander (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 || 70632b31808SJens Wiklander mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0)) { 70732b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 7083d3b0591SJens Wiklander } 7093d3b0591SJens Wiklander #endif 7103d3b0591SJens Wiklander 7113d3b0591SJens Wiklander /* It wouldn't lead to an error if it wasn't satisfied, 7123d3b0591SJens Wiklander * but check for QP >= 1 nonetheless. */ 7133d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 7143d3b0591SJens Wiklander if (is_priv && 71532b31808SJens Wiklander mbedtls_mpi_cmp_int(&ctx->QP, 0) <= 0) { 71632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 7173d3b0591SJens Wiklander } 7183d3b0591SJens Wiklander #endif 7193d3b0591SJens Wiklander 72032b31808SJens Wiklander return 0; 7213d3b0591SJens Wiklander } 7223d3b0591SJens Wiklander 7233d3b0591SJens Wiklander int mbedtls_rsa_complete(mbedtls_rsa_context *ctx) 7243d3b0591SJens Wiklander { 7253d3b0591SJens Wiklander int ret = 0; 7263d3b0591SJens Wiklander int have_N, have_P, have_Q, have_D, have_E; 7275b25c76aSJerome Forissier #if !defined(MBEDTLS_RSA_NO_CRT) 7285b25c76aSJerome Forissier int have_DP, have_DQ, have_QP; 7295b25c76aSJerome Forissier #endif 7303d3b0591SJens Wiklander int n_missing, pq_missing, d_missing, is_pub, is_priv; 7313d3b0591SJens Wiklander 7323d3b0591SJens Wiklander have_N = (mbedtls_mpi_cmp_int(&ctx->N, 0) != 0); 7333d3b0591SJens Wiklander have_P = (mbedtls_mpi_cmp_int(&ctx->P, 0) != 0); 7343d3b0591SJens Wiklander have_Q = (mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0); 7353d3b0591SJens Wiklander have_D = (mbedtls_mpi_cmp_int(&ctx->D, 0) != 0); 7363d3b0591SJens Wiklander have_E = (mbedtls_mpi_cmp_int(&ctx->E, 0) != 0); 7373d3b0591SJens Wiklander 7385b25c76aSJerome Forissier #if !defined(MBEDTLS_RSA_NO_CRT) 7395b25c76aSJerome Forissier have_DP = (mbedtls_mpi_cmp_int(&ctx->DP, 0) != 0); 7405b25c76aSJerome Forissier have_DQ = (mbedtls_mpi_cmp_int(&ctx->DQ, 0) != 0); 7415b25c76aSJerome Forissier have_QP = (mbedtls_mpi_cmp_int(&ctx->QP, 0) != 0); 7425b25c76aSJerome Forissier #endif 7435b25c76aSJerome Forissier 7443d3b0591SJens Wiklander /* 7453d3b0591SJens Wiklander * Check whether provided parameters are enough 7463d3b0591SJens Wiklander * to deduce all others. The following incomplete 7473d3b0591SJens Wiklander * parameter sets for private keys are supported: 7483d3b0591SJens Wiklander * 7493d3b0591SJens Wiklander * (1) P, Q missing. 7503d3b0591SJens Wiklander * (2) D and potentially N missing. 7513d3b0591SJens Wiklander * 7523d3b0591SJens Wiklander */ 7533d3b0591SJens Wiklander 7543d3b0591SJens Wiklander n_missing = have_P && have_Q && have_D && have_E; 7553d3b0591SJens Wiklander pq_missing = have_N && !have_P && !have_Q && have_D && have_E; 7563d3b0591SJens Wiklander d_missing = have_P && have_Q && !have_D && have_E; 7573d3b0591SJens Wiklander is_pub = have_N && !have_P && !have_Q && !have_D && have_E; 7583d3b0591SJens Wiklander 7593d3b0591SJens Wiklander /* These three alternatives are mutually exclusive */ 7603d3b0591SJens Wiklander is_priv = n_missing || pq_missing || d_missing; 7613d3b0591SJens Wiklander 76232b31808SJens Wiklander if (!is_priv && !is_pub) { 76332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 76432b31808SJens Wiklander } 7653d3b0591SJens Wiklander 7663d3b0591SJens Wiklander /* 7673d3b0591SJens Wiklander * Step 1: Deduce N if P, Q are provided. 7683d3b0591SJens Wiklander */ 7693d3b0591SJens Wiklander 77032b31808SJens Wiklander if (!have_N && have_P && have_Q) { 7713d3b0591SJens Wiklander if ((ret = mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, 77232b31808SJens Wiklander &ctx->Q)) != 0) { 77332b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 7743d3b0591SJens Wiklander } 7753d3b0591SJens Wiklander 7763d3b0591SJens Wiklander ctx->len = mbedtls_mpi_size(&ctx->N); 7773d3b0591SJens Wiklander } 7783d3b0591SJens Wiklander 7793d3b0591SJens Wiklander /* 7803d3b0591SJens Wiklander * Step 2: Deduce and verify all remaining core parameters. 7813d3b0591SJens Wiklander */ 7823d3b0591SJens Wiklander 78332b31808SJens Wiklander if (pq_missing) { 7843d3b0591SJens Wiklander ret = mbedtls_rsa_deduce_primes(&ctx->N, &ctx->E, &ctx->D, 7853d3b0591SJens Wiklander &ctx->P, &ctx->Q); 78632b31808SJens Wiklander if (ret != 0) { 78732b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 7883d3b0591SJens Wiklander } 78932b31808SJens Wiklander 79032b31808SJens Wiklander } else if (d_missing) { 7913d3b0591SJens Wiklander if ((ret = mbedtls_rsa_deduce_private_exponent(&ctx->P, 7923d3b0591SJens Wiklander &ctx->Q, 7933d3b0591SJens Wiklander &ctx->E, 79432b31808SJens Wiklander &ctx->D)) != 0) { 79532b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 7963d3b0591SJens Wiklander } 7973d3b0591SJens Wiklander } 7983d3b0591SJens Wiklander 7993d3b0591SJens Wiklander /* 8003d3b0591SJens Wiklander * Step 3: Deduce all additional parameters specific 8013d3b0591SJens Wiklander * to our current RSA implementation. 8023d3b0591SJens Wiklander */ 8033d3b0591SJens Wiklander 8043d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 80532b31808SJens Wiklander if (is_priv && !(have_DP && have_DQ && have_QP)) { 8063d3b0591SJens Wiklander ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, 8073d3b0591SJens Wiklander &ctx->DP, &ctx->DQ, &ctx->QP); 80832b31808SJens Wiklander if (ret != 0) { 80932b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 81032b31808SJens Wiklander } 8113d3b0591SJens Wiklander } 8123d3b0591SJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 8133d3b0591SJens Wiklander 8143d3b0591SJens Wiklander /* 8153d3b0591SJens Wiklander * Step 3: Basic sanity checks 8163d3b0591SJens Wiklander */ 8173d3b0591SJens Wiklander 81832b31808SJens Wiklander return rsa_check_context(ctx, is_priv, 1); 8193d3b0591SJens Wiklander } 8203d3b0591SJens Wiklander 8213d3b0591SJens Wiklander int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx, 8223d3b0591SJens Wiklander unsigned char *N, size_t N_len, 8233d3b0591SJens Wiklander unsigned char *P, size_t P_len, 8243d3b0591SJens Wiklander unsigned char *Q, size_t Q_len, 8253d3b0591SJens Wiklander unsigned char *D, size_t D_len, 8263d3b0591SJens Wiklander unsigned char *E, size_t E_len) 8273d3b0591SJens Wiklander { 8283d3b0591SJens Wiklander int ret = 0; 8293d3b0591SJens Wiklander int is_priv; 8303d3b0591SJens Wiklander 8313d3b0591SJens Wiklander /* Check if key is private or public */ 8323d3b0591SJens Wiklander is_priv = 8333d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && 8343d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && 8353d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && 8363d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && 8373d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; 8383d3b0591SJens Wiklander 83932b31808SJens Wiklander if (!is_priv) { 8403d3b0591SJens Wiklander /* If we're trying to export private parameters for a public key, 8413d3b0591SJens Wiklander * something must be wrong. */ 84232b31808SJens Wiklander if (P != NULL || Q != NULL || D != NULL) { 84332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 84432b31808SJens Wiklander } 8453d3b0591SJens Wiklander 8463d3b0591SJens Wiklander } 8473d3b0591SJens Wiklander 84832b31808SJens Wiklander if (N != NULL) { 8493d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->N, N, N_len)); 85032b31808SJens Wiklander } 8513d3b0591SJens Wiklander 85232b31808SJens Wiklander if (P != NULL) { 8533d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->P, P, P_len)); 85432b31808SJens Wiklander } 8553d3b0591SJens Wiklander 85632b31808SJens Wiklander if (Q != NULL) { 8573d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->Q, Q, Q_len)); 85832b31808SJens Wiklander } 8593d3b0591SJens Wiklander 86032b31808SJens Wiklander if (D != NULL) { 8613d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->D, D, D_len)); 86232b31808SJens Wiklander } 8633d3b0591SJens Wiklander 86432b31808SJens Wiklander if (E != NULL) { 8653d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->E, E, E_len)); 86632b31808SJens Wiklander } 8673d3b0591SJens Wiklander 8683d3b0591SJens Wiklander cleanup: 8693d3b0591SJens Wiklander 87032b31808SJens Wiklander return ret; 8713d3b0591SJens Wiklander } 8723d3b0591SJens Wiklander 8733d3b0591SJens Wiklander int mbedtls_rsa_export(const mbedtls_rsa_context *ctx, 8743d3b0591SJens Wiklander mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, 8753d3b0591SJens Wiklander mbedtls_mpi *D, mbedtls_mpi *E) 8763d3b0591SJens Wiklander { 87711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 8783d3b0591SJens Wiklander int is_priv; 8793d3b0591SJens Wiklander 8803d3b0591SJens Wiklander /* Check if key is private or public */ 8813d3b0591SJens Wiklander is_priv = 8823d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && 8833d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && 8843d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && 8853d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && 8863d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; 8873d3b0591SJens Wiklander 88832b31808SJens Wiklander if (!is_priv) { 8893d3b0591SJens Wiklander /* If we're trying to export private parameters for a public key, 8903d3b0591SJens Wiklander * something must be wrong. */ 89132b31808SJens Wiklander if (P != NULL || Q != NULL || D != NULL) { 89232b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 89332b31808SJens Wiklander } 8943d3b0591SJens Wiklander 8953d3b0591SJens Wiklander } 8963d3b0591SJens Wiklander 8973d3b0591SJens Wiklander /* Export all requested core parameters. */ 8983d3b0591SJens Wiklander 8993d3b0591SJens Wiklander if ((N != NULL && (ret = mbedtls_mpi_copy(N, &ctx->N)) != 0) || 9003d3b0591SJens Wiklander (P != NULL && (ret = mbedtls_mpi_copy(P, &ctx->P)) != 0) || 9013d3b0591SJens Wiklander (Q != NULL && (ret = mbedtls_mpi_copy(Q, &ctx->Q)) != 0) || 9023d3b0591SJens Wiklander (D != NULL && (ret = mbedtls_mpi_copy(D, &ctx->D)) != 0) || 90332b31808SJens Wiklander (E != NULL && (ret = mbedtls_mpi_copy(E, &ctx->E)) != 0)) { 90432b31808SJens Wiklander return ret; 9053d3b0591SJens Wiklander } 9063d3b0591SJens Wiklander 90732b31808SJens Wiklander return 0; 9083d3b0591SJens Wiklander } 9093d3b0591SJens Wiklander 9103d3b0591SJens Wiklander /* 9113d3b0591SJens Wiklander * Export CRT parameters 9123d3b0591SJens Wiklander * This must also be implemented if CRT is not used, for being able to 9133d3b0591SJens Wiklander * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt 9143d3b0591SJens Wiklander * can be used in this case. 9153d3b0591SJens Wiklander */ 9163d3b0591SJens Wiklander int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx, 9173d3b0591SJens Wiklander mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP) 9183d3b0591SJens Wiklander { 91911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 9203d3b0591SJens Wiklander int is_priv; 9213d3b0591SJens Wiklander 9223d3b0591SJens Wiklander /* Check if key is private or public */ 9233d3b0591SJens Wiklander is_priv = 9243d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && 9253d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && 9263d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && 9273d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && 9283d3b0591SJens Wiklander mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; 9293d3b0591SJens Wiklander 93032b31808SJens Wiklander if (!is_priv) { 93132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 93232b31808SJens Wiklander } 9333d3b0591SJens Wiklander 9343d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 9353d3b0591SJens Wiklander /* Export all requested blinding parameters. */ 9363d3b0591SJens Wiklander if ((DP != NULL && (ret = mbedtls_mpi_copy(DP, &ctx->DP)) != 0) || 9373d3b0591SJens Wiklander (DQ != NULL && (ret = mbedtls_mpi_copy(DQ, &ctx->DQ)) != 0) || 93832b31808SJens Wiklander (QP != NULL && (ret = mbedtls_mpi_copy(QP, &ctx->QP)) != 0)) { 93932b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 9403d3b0591SJens Wiklander } 9413d3b0591SJens Wiklander #else 9423d3b0591SJens Wiklander if ((ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, 94332b31808SJens Wiklander DP, DQ, QP)) != 0) { 94432b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); 9453d3b0591SJens Wiklander } 9463d3b0591SJens Wiklander #endif 9473d3b0591SJens Wiklander 94832b31808SJens Wiklander return 0; 949817466cbSJens Wiklander } 950817466cbSJens Wiklander 951817466cbSJens Wiklander /* 952817466cbSJens Wiklander * Initialize an RSA context 953817466cbSJens Wiklander */ 95432b31808SJens Wiklander void mbedtls_rsa_init(mbedtls_rsa_context *ctx) 955817466cbSJens Wiklander { 956817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_rsa_context)); 957817466cbSJens Wiklander 95832b31808SJens Wiklander ctx->padding = MBEDTLS_RSA_PKCS_V15; 95932b31808SJens Wiklander ctx->hash_id = MBEDTLS_MD_NONE; 960817466cbSJens Wiklander 961817466cbSJens Wiklander #if defined(MBEDTLS_THREADING_C) 9627901324dSJerome Forissier /* Set ctx->ver to nonzero to indicate that the mutex has been 9637901324dSJerome Forissier * initialized and will need to be freed. */ 9647901324dSJerome Forissier ctx->ver = 1; 965817466cbSJens Wiklander mbedtls_mutex_init(&ctx->mutex); 966817466cbSJens Wiklander #endif 967817466cbSJens Wiklander } 968817466cbSJens Wiklander 969817466cbSJens Wiklander /* 970817466cbSJens Wiklander * Set padding for an existing RSA context 971817466cbSJens Wiklander */ 97232b31808SJens Wiklander int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding, 97332b31808SJens Wiklander mbedtls_md_type_t hash_id) 974817466cbSJens Wiklander { 97532b31808SJens Wiklander switch (padding) { 97632b31808SJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 97732b31808SJens Wiklander case MBEDTLS_RSA_PKCS_V15: 97832b31808SJens Wiklander break; 97932b31808SJens Wiklander #endif 98032b31808SJens Wiklander 98132b31808SJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 98232b31808SJens Wiklander case MBEDTLS_RSA_PKCS_V21: 98332b31808SJens Wiklander break; 98432b31808SJens Wiklander #endif 98532b31808SJens Wiklander default: 98632b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 98732b31808SJens Wiklander } 98832b31808SJens Wiklander 98932b31808SJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 99032b31808SJens Wiklander if ((padding == MBEDTLS_RSA_PKCS_V21) && 99132b31808SJens Wiklander (hash_id != MBEDTLS_MD_NONE)) { 99232b31808SJens Wiklander /* Just make sure this hash is supported in this build. */ 993*b0563631STom Van Eyck if (mbedtls_md_info_from_type(hash_id) == NULL) { 99432b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 99532b31808SJens Wiklander } 99632b31808SJens Wiklander } 99732b31808SJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 9983d3b0591SJens Wiklander 999817466cbSJens Wiklander ctx->padding = padding; 1000817466cbSJens Wiklander ctx->hash_id = hash_id; 100132b31808SJens Wiklander 100232b31808SJens Wiklander return 0; 100332b31808SJens Wiklander } 100432b31808SJens Wiklander 100532b31808SJens Wiklander /* 100632b31808SJens Wiklander * Get padding mode of initialized RSA context 100732b31808SJens Wiklander */ 100832b31808SJens Wiklander int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx) 100932b31808SJens Wiklander { 101032b31808SJens Wiklander return ctx->padding; 101132b31808SJens Wiklander } 101232b31808SJens Wiklander 101332b31808SJens Wiklander /* 101432b31808SJens Wiklander * Get hash identifier of mbedtls_md_type_t type 101532b31808SJens Wiklander */ 101632b31808SJens Wiklander int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx) 101732b31808SJens Wiklander { 101832b31808SJens Wiklander return ctx->hash_id; 1019817466cbSJens Wiklander } 1020817466cbSJens Wiklander 10213d3b0591SJens Wiklander /* 1022*b0563631STom Van Eyck * Get length in bits of RSA modulus 1023*b0563631STom Van Eyck */ 1024*b0563631STom Van Eyck size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx) 1025*b0563631STom Van Eyck { 1026*b0563631STom Van Eyck return mbedtls_mpi_bitlen(&ctx->N); 1027*b0563631STom Van Eyck } 1028*b0563631STom Van Eyck 1029*b0563631STom Van Eyck /* 10303d3b0591SJens Wiklander * Get length in bytes of RSA modulus 10313d3b0591SJens Wiklander */ 10323d3b0591SJens Wiklander size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx) 10333d3b0591SJens Wiklander { 103432b31808SJens Wiklander return ctx->len; 10353d3b0591SJens Wiklander } 10363d3b0591SJens Wiklander 1037817466cbSJens Wiklander #if defined(MBEDTLS_GENPRIME) 1038817466cbSJens Wiklander 1039817466cbSJens Wiklander /* 1040817466cbSJens Wiklander * Generate an RSA keypair 10413d3b0591SJens Wiklander * 10423d3b0591SJens Wiklander * This generation method follows the RSA key pair generation procedure of 10433d3b0591SJens Wiklander * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. 1044817466cbSJens Wiklander */ 1045817466cbSJens Wiklander int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx, 1046817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1047817466cbSJens Wiklander void *p_rng, 1048817466cbSJens Wiklander unsigned int nbits, int exponent) 1049817466cbSJens Wiklander { 105011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 10513d3b0591SJens Wiklander mbedtls_mpi H, G, L; 10523d3b0591SJens Wiklander int prime_quality = 0; 1053817466cbSJens Wiklander 10543d3b0591SJens Wiklander /* 10553d3b0591SJens Wiklander * If the modulus is 1024 bit long or shorter, then the security strength of 10563d3b0591SJens Wiklander * the RSA algorithm is less than or equal to 80 bits and therefore an error 10573d3b0591SJens Wiklander * rate of 2^-80 is sufficient. 10583d3b0591SJens Wiklander */ 105932b31808SJens Wiklander if (nbits > 1024) { 10603d3b0591SJens Wiklander prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; 106132b31808SJens Wiklander } 1062817466cbSJens Wiklander 10633d3b0591SJens Wiklander mbedtls_mpi_init(&H); 10643d3b0591SJens Wiklander mbedtls_mpi_init(&G); 10653d3b0591SJens Wiklander mbedtls_mpi_init(&L); 1066817466cbSJens Wiklander 1067*b0563631STom Van Eyck if (exponent < 3 || nbits % 2 != 0) { 1068*b0563631STom Van Eyck ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 1069*b0563631STom Van Eyck goto cleanup; 1070*b0563631STom Van Eyck } 1071*b0563631STom Van Eyck 1072*b0563631STom Van Eyck if (nbits < MBEDTLS_RSA_GEN_KEY_MIN_BITS) { 10737901324dSJerome Forissier ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 10747901324dSJerome Forissier goto cleanup; 10757901324dSJerome Forissier } 10767901324dSJerome Forissier 1077817466cbSJens Wiklander /* 1078817466cbSJens Wiklander * find primes P and Q with Q < P so that: 10793d3b0591SJens Wiklander * 1. |P-Q| > 2^( nbits / 2 - 100 ) 10803d3b0591SJens Wiklander * 2. GCD( E, (P-1)*(Q-1) ) == 1 10813d3b0591SJens Wiklander * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) 1082817466cbSJens Wiklander */ 1083817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->E, exponent)); 1084817466cbSJens Wiklander 108532b31808SJens Wiklander do { 10863d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->P, nbits >> 1, 10873d3b0591SJens Wiklander prime_quality, f_rng, p_rng)); 1088817466cbSJens Wiklander 10893d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->Q, nbits >> 1, 10903d3b0591SJens Wiklander prime_quality, f_rng, p_rng)); 1091817466cbSJens Wiklander 10923d3b0591SJens Wiklander /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ 10933d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&H, &ctx->P, &ctx->Q)); 109432b31808SJens Wiklander if (mbedtls_mpi_bitlen(&H) <= ((nbits >= 200) ? ((nbits >> 1) - 99) : 0)) { 1095817466cbSJens Wiklander continue; 109632b31808SJens Wiklander } 1097817466cbSJens Wiklander 10983d3b0591SJens Wiklander /* not required by any standards, but some users rely on the fact that P > Q */ 109932b31808SJens Wiklander if (H.s < 0) { 1100817466cbSJens Wiklander mbedtls_mpi_swap(&ctx->P, &ctx->Q); 110132b31808SJens Wiklander } 1102817466cbSJens Wiklander 11033d3b0591SJens Wiklander /* Temporarily replace P,Q by P-1, Q-1 */ 11043d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->P, &ctx->P, 1)); 11053d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->Q, &ctx->Q, 1)); 11063d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&H, &ctx->P, &ctx->Q)); 1107817466cbSJens Wiklander 11083d3b0591SJens Wiklander /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */ 11093d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->E, &H)); 111032b31808SJens Wiklander if (mbedtls_mpi_cmp_int(&G, 1) != 0) { 11113d3b0591SJens Wiklander continue; 111232b31808SJens Wiklander } 11133d3b0591SJens Wiklander 11143d3b0591SJens Wiklander /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */ 11153d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->P, &ctx->Q)); 11163d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&L, NULL, &H, &G)); 11173d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->D, &ctx->E, &L)); 11183d3b0591SJens Wiklander 111932b31808SJens Wiklander if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) { // (FIPS 186-4 §B.3.1 criterion 3(a)) 11203d3b0591SJens Wiklander continue; 112132b31808SJens Wiklander } 11223d3b0591SJens Wiklander 11233d3b0591SJens Wiklander break; 112432b31808SJens Wiklander } while (1); 11253d3b0591SJens Wiklander 11263d3b0591SJens Wiklander /* Restore P,Q */ 11273d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->P, &ctx->P, 1)); 11283d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->Q, &ctx->Q, 1)); 11293d3b0591SJens Wiklander 11303d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q)); 11313d3b0591SJens Wiklander 11323d3b0591SJens Wiklander ctx->len = mbedtls_mpi_size(&ctx->N); 11333d3b0591SJens Wiklander 11343d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 1135817466cbSJens Wiklander /* 1136817466cbSJens Wiklander * DP = D mod (P - 1) 1137817466cbSJens Wiklander * DQ = D mod (Q - 1) 1138817466cbSJens Wiklander * QP = Q^-1 mod P 1139817466cbSJens Wiklander */ 11403d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, 11413d3b0591SJens Wiklander &ctx->DP, &ctx->DQ, &ctx->QP)); 11423d3b0591SJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 1143817466cbSJens Wiklander 11443d3b0591SJens Wiklander /* Double-check */ 11453d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_check_privkey(ctx)); 1146817466cbSJens Wiklander 1147817466cbSJens Wiklander cleanup: 1148817466cbSJens Wiklander 11493d3b0591SJens Wiklander mbedtls_mpi_free(&H); 11503d3b0591SJens Wiklander mbedtls_mpi_free(&G); 11513d3b0591SJens Wiklander mbedtls_mpi_free(&L); 1152817466cbSJens Wiklander 115332b31808SJens Wiklander if (ret != 0) { 1154817466cbSJens Wiklander mbedtls_rsa_free(ctx); 11557901324dSJerome Forissier 115632b31808SJens Wiklander if ((-ret & ~0x7f) == 0) { 11577901324dSJerome Forissier ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret); 115832b31808SJens Wiklander } 115932b31808SJens Wiklander return ret; 1160817466cbSJens Wiklander } 1161817466cbSJens Wiklander 116232b31808SJens Wiklander return 0; 1163817466cbSJens Wiklander } 1164817466cbSJens Wiklander 1165817466cbSJens Wiklander #endif /* MBEDTLS_GENPRIME */ 1166817466cbSJens Wiklander 1167817466cbSJens Wiklander /* 1168817466cbSJens Wiklander * Check a public RSA key 1169817466cbSJens Wiklander */ 1170817466cbSJens Wiklander int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx) 1171817466cbSJens Wiklander { 117232b31808SJens Wiklander if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */) != 0) { 117332b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 117432b31808SJens Wiklander } 11753d3b0591SJens Wiklander 117632b31808SJens Wiklander if (mbedtls_mpi_bitlen(&ctx->N) < 128) { 117732b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 11783d3b0591SJens Wiklander } 1179817466cbSJens Wiklander 11803d3b0591SJens Wiklander if (mbedtls_mpi_get_bit(&ctx->E, 0) == 0 || 11813d3b0591SJens Wiklander mbedtls_mpi_bitlen(&ctx->E) < 2 || 118232b31808SJens Wiklander mbedtls_mpi_cmp_mpi(&ctx->E, &ctx->N) >= 0) { 118332b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 11843d3b0591SJens Wiklander } 1185817466cbSJens Wiklander 118632b31808SJens Wiklander return 0; 1187817466cbSJens Wiklander } 1188817466cbSJens Wiklander 1189817466cbSJens Wiklander /* 11903d3b0591SJens Wiklander * Check for the consistency of all fields in an RSA private key context 1191817466cbSJens Wiklander */ 1192817466cbSJens Wiklander int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx) 1193817466cbSJens Wiklander { 11943d3b0591SJens Wiklander if (mbedtls_rsa_check_pubkey(ctx) != 0 || 119532b31808SJens Wiklander rsa_check_context(ctx, 1 /* private */, 1 /* blinding */) != 0) { 119632b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 1197817466cbSJens Wiklander } 1198817466cbSJens Wiklander 11993d3b0591SJens Wiklander if (mbedtls_rsa_validate_params(&ctx->N, &ctx->P, &ctx->Q, 120032b31808SJens Wiklander &ctx->D, &ctx->E, NULL, NULL) != 0) { 120132b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 12023d3b0591SJens Wiklander } 1203817466cbSJens Wiklander 12043d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 12053d3b0591SJens Wiklander else if (mbedtls_rsa_validate_crt(&ctx->P, &ctx->Q, &ctx->D, 120632b31808SJens Wiklander &ctx->DP, &ctx->DQ, &ctx->QP) != 0) { 120732b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 12083d3b0591SJens Wiklander } 12093d3b0591SJens Wiklander #endif 1210817466cbSJens Wiklander 121132b31808SJens Wiklander return 0; 1212817466cbSJens Wiklander } 1213817466cbSJens Wiklander 1214817466cbSJens Wiklander /* 1215817466cbSJens Wiklander * Check if contexts holding a public and private key match 1216817466cbSJens Wiklander */ 12173d3b0591SJens Wiklander int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, 12183d3b0591SJens Wiklander const mbedtls_rsa_context *prv) 1219817466cbSJens Wiklander { 1220817466cbSJens Wiklander if (mbedtls_rsa_check_pubkey(pub) != 0 || 122132b31808SJens Wiklander mbedtls_rsa_check_privkey(prv) != 0) { 122232b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 1223817466cbSJens Wiklander } 1224817466cbSJens Wiklander 1225817466cbSJens Wiklander if (mbedtls_mpi_cmp_mpi(&pub->N, &prv->N) != 0 || 122632b31808SJens Wiklander mbedtls_mpi_cmp_mpi(&pub->E, &prv->E) != 0) { 122732b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 1228817466cbSJens Wiklander } 1229817466cbSJens Wiklander 123032b31808SJens Wiklander return 0; 1231817466cbSJens Wiklander } 1232817466cbSJens Wiklander 1233817466cbSJens Wiklander /* 1234817466cbSJens Wiklander * Do an RSA public key operation 1235817466cbSJens Wiklander */ 1236817466cbSJens Wiklander int mbedtls_rsa_public(mbedtls_rsa_context *ctx, 1237817466cbSJens Wiklander const unsigned char *input, 1238817466cbSJens Wiklander unsigned char *output) 1239817466cbSJens Wiklander { 124011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1241817466cbSJens Wiklander size_t olen; 1242817466cbSJens Wiklander mbedtls_mpi T; 12433d3b0591SJens Wiklander 124432b31808SJens Wiklander if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */)) { 124532b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 124632b31808SJens Wiklander } 1247817466cbSJens Wiklander 1248817466cbSJens Wiklander mbedtls_mpi_init(&T); 1249817466cbSJens Wiklander 1250817466cbSJens Wiklander #if defined(MBEDTLS_THREADING_C) 125132b31808SJens Wiklander if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { 125232b31808SJens Wiklander return ret; 125332b31808SJens Wiklander } 1254817466cbSJens Wiklander #endif 1255817466cbSJens Wiklander 1256817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len)); 1257817466cbSJens Wiklander 125832b31808SJens Wiklander if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) { 1259817466cbSJens Wiklander ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 1260817466cbSJens Wiklander goto cleanup; 1261817466cbSJens Wiklander } 1262817466cbSJens Wiklander 1263817466cbSJens Wiklander olen = ctx->len; 1264817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN)); 1265817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); 1266817466cbSJens Wiklander 1267817466cbSJens Wiklander cleanup: 1268817466cbSJens Wiklander #if defined(MBEDTLS_THREADING_C) 126932b31808SJens Wiklander if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { 127032b31808SJens Wiklander return MBEDTLS_ERR_THREADING_MUTEX_ERROR; 127132b31808SJens Wiklander } 1272817466cbSJens Wiklander #endif 1273817466cbSJens Wiklander 1274817466cbSJens Wiklander mbedtls_mpi_free(&T); 1275817466cbSJens Wiklander 127632b31808SJens Wiklander if (ret != 0) { 127732b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret); 127832b31808SJens Wiklander } 1279817466cbSJens Wiklander 128032b31808SJens Wiklander return 0; 1281817466cbSJens Wiklander } 1282817466cbSJens Wiklander 1283817466cbSJens Wiklander /* 1284817466cbSJens Wiklander * Generate or update blinding values, see section 10 of: 1285817466cbSJens Wiklander * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, 1286817466cbSJens Wiklander * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer 1287817466cbSJens Wiklander * Berlin Heidelberg, 1996. p. 104-113. 1288817466cbSJens Wiklander */ 1289817466cbSJens Wiklander static int rsa_prepare_blinding(mbedtls_rsa_context *ctx, 1290817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1291817466cbSJens Wiklander { 1292817466cbSJens Wiklander int ret, count = 0; 12937901324dSJerome Forissier mbedtls_mpi R; 12947901324dSJerome Forissier 12957901324dSJerome Forissier mbedtls_mpi_init(&R); 1296817466cbSJens Wiklander 129732b31808SJens Wiklander if (ctx->Vf.p != NULL) { 1298817466cbSJens Wiklander /* We already have blinding values, just update them by squaring */ 1299817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi)); 1300817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N)); 1301817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf)); 1302817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->N)); 1303817466cbSJens Wiklander 1304817466cbSJens Wiklander goto cleanup; 1305817466cbSJens Wiklander } 1306817466cbSJens Wiklander 1307817466cbSJens Wiklander /* Unblinding value: Vf = random number, invertible mod N */ 1308817466cbSJens Wiklander do { 130932b31808SJens Wiklander if (count++ > 10) { 13107901324dSJerome Forissier ret = MBEDTLS_ERR_RSA_RNG_FAILED; 13117901324dSJerome Forissier goto cleanup; 13127901324dSJerome Forissier } 1313817466cbSJens Wiklander 1314817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->Vf, ctx->len - 1, f_rng, p_rng)); 1315817466cbSJens Wiklander 13167901324dSJerome Forissier /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */ 13177901324dSJerome Forissier MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, ctx->len - 1, f_rng, p_rng)); 13187901324dSJerome Forissier MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vf, &R)); 13197901324dSJerome Forissier MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N)); 13207901324dSJerome Forissier 13217901324dSJerome Forissier /* At this point, Vi is invertible mod N if and only if both Vf and R 13227901324dSJerome Forissier * are invertible mod N. If one of them isn't, we don't need to know 13237901324dSJerome Forissier * which one, we just loop and choose new values for both of them. 13247901324dSJerome Forissier * (Each iteration succeeds with overwhelming probability.) */ 13257901324dSJerome Forissier ret = mbedtls_mpi_inv_mod(&ctx->Vi, &ctx->Vi, &ctx->N); 132632b31808SJens Wiklander if (ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { 13277901324dSJerome Forissier goto cleanup; 132832b31808SJens Wiklander } 13297901324dSJerome Forissier 13307901324dSJerome Forissier } while (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); 13317901324dSJerome Forissier 13327901324dSJerome Forissier /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ 13337901324dSJerome Forissier MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &R)); 13347901324dSJerome Forissier MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N)); 13357901324dSJerome Forissier 13367901324dSJerome Forissier /* Blinding value: Vi = Vf^(-e) mod N 13377901324dSJerome Forissier * (Vi already contains Vf^-1 at this point) */ 1338817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN)); 1339817466cbSJens Wiklander 1340817466cbSJens Wiklander 1341817466cbSJens Wiklander cleanup: 13427901324dSJerome Forissier mbedtls_mpi_free(&R); 13437901324dSJerome Forissier 134432b31808SJens Wiklander return ret; 1345817466cbSJens Wiklander } 1346817466cbSJens Wiklander 1347817466cbSJens Wiklander /* 1348*b0563631STom Van Eyck * Unblind 1349*b0563631STom Van Eyck * T = T * Vf mod N 1350*b0563631STom Van Eyck */ 1351*b0563631STom Van Eyck static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N) 1352*b0563631STom Van Eyck { 1353*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1354*b0563631STom Van Eyck const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); 1355*b0563631STom Van Eyck const size_t nlimbs = N->n; 1356*b0563631STom Van Eyck const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs); 1357*b0563631STom Van Eyck mbedtls_mpi RR, M_T; 1358*b0563631STom Van Eyck 1359*b0563631STom Van Eyck mbedtls_mpi_init(&RR); 1360*b0563631STom Van Eyck mbedtls_mpi_init(&M_T); 1361*b0563631STom Van Eyck 1362*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N)); 1363*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs)); 1364*b0563631STom Van Eyck 1365*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs)); 1366*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs)); 1367*b0563631STom Van Eyck 1368*b0563631STom Van Eyck /* T = T * Vf mod N 1369*b0563631STom Van Eyck * Reminder: montmul(A, B, N) = A * B * R^-1 mod N 1370*b0563631STom Van Eyck * Usually both operands are multiplied by R mod N beforehand (by calling 1371*b0563631STom Van Eyck * `to_mont_rep()` on them), yielding a result that's also * R mod N (aka 1372*b0563631STom Van Eyck * "in the Montgomery domain"). Here we only multiply one operand by R mod 1373*b0563631STom Van Eyck * N, so the result is directly what we want - no need to call 1374*b0563631STom Van Eyck * `from_mont_rep()` on it. */ 1375*b0563631STom Van Eyck mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p); 1376*b0563631STom Van Eyck mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p); 1377*b0563631STom Van Eyck 1378*b0563631STom Van Eyck cleanup: 1379*b0563631STom Van Eyck 1380*b0563631STom Van Eyck mbedtls_mpi_free(&RR); 1381*b0563631STom Van Eyck mbedtls_mpi_free(&M_T); 1382*b0563631STom Van Eyck 1383*b0563631STom Van Eyck return ret; 1384*b0563631STom Van Eyck } 1385*b0563631STom Van Eyck 1386*b0563631STom Van Eyck /* 1387817466cbSJens Wiklander * Exponent blinding supposed to prevent side-channel attacks using multiple 1388817466cbSJens Wiklander * traces of measurements to recover the RSA key. The more collisions are there, 1389817466cbSJens Wiklander * the more bits of the key can be recovered. See [3]. 1390817466cbSJens Wiklander * 1391817466cbSJens Wiklander * Collecting n collisions with m bit long blinding value requires 2^(m-m/n) 1392039e02dfSJerome Forissier * observations on average. 1393817466cbSJens Wiklander * 1394817466cbSJens Wiklander * For example with 28 byte blinding to achieve 2 collisions the adversary has 1395039e02dfSJerome Forissier * to make 2^112 observations on average. 1396817466cbSJens Wiklander * 1397817466cbSJens Wiklander * (With the currently (as of 2017 April) known best algorithms breaking 2048 1398817466cbSJens Wiklander * bit RSA requires approximately as much time as trying out 2^112 random keys. 1399817466cbSJens Wiklander * Thus in this sense with 28 byte blinding the security is not reduced by 1400817466cbSJens Wiklander * side-channel attacks like the one in [3]) 1401817466cbSJens Wiklander * 1402817466cbSJens Wiklander * This countermeasure does not help if the key recovery is possible with a 1403817466cbSJens Wiklander * single trace. 1404817466cbSJens Wiklander */ 1405817466cbSJens Wiklander #define RSA_EXPONENT_BLINDING 28 1406817466cbSJens Wiklander 1407817466cbSJens Wiklander /* 1408817466cbSJens Wiklander * Do an RSA private key operation 1409817466cbSJens Wiklander */ 1410817466cbSJens Wiklander int mbedtls_rsa_private(mbedtls_rsa_context *ctx, 1411817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1412817466cbSJens Wiklander void *p_rng, 1413817466cbSJens Wiklander const unsigned char *input, 1414817466cbSJens Wiklander unsigned char *output) 1415817466cbSJens Wiklander { 141611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1417817466cbSJens Wiklander size_t olen; 14183d3b0591SJens Wiklander 14193d3b0591SJens Wiklander /* Temporary holding the result */ 14203d3b0591SJens Wiklander mbedtls_mpi T; 14213d3b0591SJens Wiklander 14223d3b0591SJens Wiklander /* Temporaries holding P-1, Q-1 and the 14233d3b0591SJens Wiklander * exponent blinding factor, respectively. */ 1424817466cbSJens Wiklander mbedtls_mpi P1, Q1, R; 14253d3b0591SJens Wiklander 14263d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 14273d3b0591SJens Wiklander /* Temporaries holding the results mod p resp. mod q. */ 14283d3b0591SJens Wiklander mbedtls_mpi TP, TQ; 14293d3b0591SJens Wiklander 14303d3b0591SJens Wiklander /* Temporaries holding the blinded exponents for 14313d3b0591SJens Wiklander * the mod p resp. mod q computation (if used). */ 1432817466cbSJens Wiklander mbedtls_mpi DP_blind, DQ_blind; 14333d3b0591SJens Wiklander #else 14343d3b0591SJens Wiklander /* Temporary holding the blinded exponent (if used). */ 14353d3b0591SJens Wiklander mbedtls_mpi D_blind; 14363d3b0591SJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 14373d3b0591SJens Wiklander 14383d3b0591SJens Wiklander /* Temporaries holding the initial input and the double 14393d3b0591SJens Wiklander * checked result; should be the same in the end. */ 1440*b0563631STom Van Eyck mbedtls_mpi input_blinded, check_result_blinded; 14413d3b0591SJens Wiklander 144232b31808SJens Wiklander if (f_rng == NULL) { 144332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 144432b31808SJens Wiklander } 14453d3b0591SJens Wiklander 14463d3b0591SJens Wiklander if (rsa_check_context(ctx, 1 /* private key checks */, 144732b31808SJens Wiklander 1 /* blinding on */) != 0) { 144832b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 14493d3b0591SJens Wiklander } 14503d3b0591SJens Wiklander 14513d3b0591SJens Wiklander #if defined(MBEDTLS_THREADING_C) 145232b31808SJens Wiklander if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { 145332b31808SJens Wiklander return ret; 145432b31808SJens Wiklander } 1455817466cbSJens Wiklander #endif 1456817466cbSJens Wiklander 14573d3b0591SJens Wiklander /* MPI Initialization */ 14583d3b0591SJens Wiklander mbedtls_mpi_init(&T); 1459817466cbSJens Wiklander 14603d3b0591SJens Wiklander mbedtls_mpi_init(&P1); 14613d3b0591SJens Wiklander mbedtls_mpi_init(&Q1); 14623d3b0591SJens Wiklander mbedtls_mpi_init(&R); 1463817466cbSJens Wiklander 1464817466cbSJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 1465817466cbSJens Wiklander mbedtls_mpi_init(&D_blind); 1466817466cbSJens Wiklander #else 1467817466cbSJens Wiklander mbedtls_mpi_init(&DP_blind); 1468817466cbSJens Wiklander mbedtls_mpi_init(&DQ_blind); 1469817466cbSJens Wiklander #endif 1470817466cbSJens Wiklander 14713d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 14723d3b0591SJens Wiklander mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ); 1473817466cbSJens Wiklander #endif 1474817466cbSJens Wiklander 1475*b0563631STom Van Eyck mbedtls_mpi_init(&input_blinded); 1476*b0563631STom Van Eyck mbedtls_mpi_init(&check_result_blinded); 14773d3b0591SJens Wiklander 14783d3b0591SJens Wiklander /* End of MPI initialization */ 14793d3b0591SJens Wiklander 1480817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len)); 148132b31808SJens Wiklander if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) { 1482817466cbSJens Wiklander ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 1483817466cbSJens Wiklander goto cleanup; 1484817466cbSJens Wiklander } 1485817466cbSJens Wiklander 1486817466cbSJens Wiklander /* 1487817466cbSJens Wiklander * Blinding 1488817466cbSJens Wiklander * T = T * Vi mod N 1489817466cbSJens Wiklander */ 1490817466cbSJens Wiklander MBEDTLS_MPI_CHK(rsa_prepare_blinding(ctx, f_rng, p_rng)); 1491817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi)); 1492817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); 1493817466cbSJens Wiklander 1494*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T)); 1495*b0563631STom Van Eyck 1496817466cbSJens Wiklander /* 1497817466cbSJens Wiklander * Exponent blinding 1498817466cbSJens Wiklander */ 1499817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&P1, &ctx->P, 1)); 1500817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&Q1, &ctx->Q, 1)); 1501817466cbSJens Wiklander 1502817466cbSJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 1503817466cbSJens Wiklander /* 1504817466cbSJens Wiklander * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D 1505817466cbSJens Wiklander */ 1506817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, 1507817466cbSJens Wiklander f_rng, p_rng)); 1508817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1)); 1509817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R)); 1510817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D)); 1511817466cbSJens Wiklander #else 1512817466cbSJens Wiklander /* 1513817466cbSJens Wiklander * DP_blind = ( P - 1 ) * R + DP 1514817466cbSJens Wiklander */ 1515817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, 1516817466cbSJens Wiklander f_rng, p_rng)); 1517817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DP_blind, &P1, &R)); 1518817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind, 1519817466cbSJens Wiklander &ctx->DP)); 1520817466cbSJens Wiklander 1521817466cbSJens Wiklander /* 1522817466cbSJens Wiklander * DQ_blind = ( Q - 1 ) * R + DQ 1523817466cbSJens Wiklander */ 1524817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, 1525817466cbSJens Wiklander f_rng, p_rng)); 1526817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R)); 1527817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind, 1528817466cbSJens Wiklander &ctx->DQ)); 1529817466cbSJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 1530817466cbSJens Wiklander 1531817466cbSJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 1532*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN)); 1533817466cbSJens Wiklander #else 1534817466cbSJens Wiklander /* 1535817466cbSJens Wiklander * Faster decryption using the CRT 1536817466cbSJens Wiklander * 15373d3b0591SJens Wiklander * TP = input ^ dP mod P 15383d3b0591SJens Wiklander * TQ = input ^ dQ mod Q 1539817466cbSJens Wiklander */ 15403d3b0591SJens Wiklander 1541*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP)); 1542*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ)); 1543817466cbSJens Wiklander 1544817466cbSJens Wiklander /* 15453d3b0591SJens Wiklander * T = (TP - TQ) * (Q^-1 mod P) mod P 1546817466cbSJens Wiklander */ 15473d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&T, &TP, &TQ)); 15483d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->QP)); 15493d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &TP, &ctx->P)); 1550817466cbSJens Wiklander 1551817466cbSJens Wiklander /* 15523d3b0591SJens Wiklander * T = TQ + T * Q 1553817466cbSJens Wiklander */ 15543d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->Q)); 15553d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP)); 1556817466cbSJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 1557817466cbSJens Wiklander 1558*b0563631STom Van Eyck /* Verify the result to prevent glitching attacks. */ 1559*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E, 1560*b0563631STom Van Eyck &ctx->N, &ctx->RN)); 1561*b0563631STom Van Eyck if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) { 1562*b0563631STom Van Eyck ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; 1563*b0563631STom Van Eyck goto cleanup; 1564*b0563631STom Van Eyck } 1565*b0563631STom Van Eyck 1566817466cbSJens Wiklander /* 1567817466cbSJens Wiklander * Unblind 1568817466cbSJens Wiklander * T = T * Vf mod N 1569817466cbSJens Wiklander */ 1570*b0563631STom Van Eyck MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); 15713d3b0591SJens Wiklander 1572817466cbSJens Wiklander olen = ctx->len; 1573817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); 1574817466cbSJens Wiklander 1575817466cbSJens Wiklander cleanup: 1576817466cbSJens Wiklander #if defined(MBEDTLS_THREADING_C) 157732b31808SJens Wiklander if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { 157832b31808SJens Wiklander return MBEDTLS_ERR_THREADING_MUTEX_ERROR; 157932b31808SJens Wiklander } 1580817466cbSJens Wiklander #endif 1581817466cbSJens Wiklander 15823d3b0591SJens Wiklander mbedtls_mpi_free(&P1); 15833d3b0591SJens Wiklander mbedtls_mpi_free(&Q1); 15843d3b0591SJens Wiklander mbedtls_mpi_free(&R); 1585817466cbSJens Wiklander 1586817466cbSJens Wiklander #if defined(MBEDTLS_RSA_NO_CRT) 1587817466cbSJens Wiklander mbedtls_mpi_free(&D_blind); 1588817466cbSJens Wiklander #else 1589817466cbSJens Wiklander mbedtls_mpi_free(&DP_blind); 1590817466cbSJens Wiklander mbedtls_mpi_free(&DQ_blind); 1591817466cbSJens Wiklander #endif 1592817466cbSJens Wiklander 15933d3b0591SJens Wiklander mbedtls_mpi_free(&T); 15943d3b0591SJens Wiklander 15953d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 15963d3b0591SJens Wiklander mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ); 15973d3b0591SJens Wiklander #endif 15983d3b0591SJens Wiklander 1599*b0563631STom Van Eyck mbedtls_mpi_free(&check_result_blinded); 1600*b0563631STom Van Eyck mbedtls_mpi_free(&input_blinded); 16013d3b0591SJens Wiklander 160232b31808SJens Wiklander if (ret != 0 && ret >= -0x007f) { 160332b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret); 160432b31808SJens Wiklander } 1605817466cbSJens Wiklander 160632b31808SJens Wiklander return ret; 1607817466cbSJens Wiklander } 1608817466cbSJens Wiklander 1609817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 1610817466cbSJens Wiklander /** 1611817466cbSJens Wiklander * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. 1612817466cbSJens Wiklander * 1613817466cbSJens Wiklander * \param dst buffer to mask 1614817466cbSJens Wiklander * \param dlen length of destination buffer 1615817466cbSJens Wiklander * \param src source of the mask generation 1616817466cbSJens Wiklander * \param slen length of the source buffer 161732b31808SJens Wiklander * \param md_alg message digest to use 1618817466cbSJens Wiklander */ 16193d3b0591SJens Wiklander static int mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, 162032b31808SJens Wiklander size_t slen, mbedtls_md_type_t md_alg) 1621817466cbSJens Wiklander { 1622817466cbSJens Wiklander unsigned char counter[4]; 1623817466cbSJens Wiklander unsigned char *p; 1624817466cbSJens Wiklander unsigned int hlen; 1625817466cbSJens Wiklander size_t i, use_len; 1626*b0563631STom Van Eyck unsigned char mask[MBEDTLS_MD_MAX_SIZE]; 16273d3b0591SJens Wiklander int ret = 0; 162832b31808SJens Wiklander const mbedtls_md_info_t *md_info; 162932b31808SJens Wiklander mbedtls_md_context_t md_ctx; 1630817466cbSJens Wiklander 163132b31808SJens Wiklander mbedtls_md_init(&md_ctx); 163232b31808SJens Wiklander md_info = mbedtls_md_info_from_type(md_alg); 163332b31808SJens Wiklander if (md_info == NULL) { 163432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 163532b31808SJens Wiklander } 163632b31808SJens Wiklander 163732b31808SJens Wiklander mbedtls_md_init(&md_ctx); 163832b31808SJens Wiklander if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { 163932b31808SJens Wiklander goto exit; 164032b31808SJens Wiklander } 164132b31808SJens Wiklander 164232b31808SJens Wiklander hlen = mbedtls_md_get_size(md_info); 164332b31808SJens Wiklander 164432b31808SJens Wiklander memset(mask, 0, sizeof(mask)); 1645817466cbSJens Wiklander memset(counter, 0, 4); 1646817466cbSJens Wiklander 1647817466cbSJens Wiklander /* Generate and apply dbMask */ 1648817466cbSJens Wiklander p = dst; 1649817466cbSJens Wiklander 165032b31808SJens Wiklander while (dlen > 0) { 1651817466cbSJens Wiklander use_len = hlen; 165232b31808SJens Wiklander if (dlen < hlen) { 1653817466cbSJens Wiklander use_len = dlen; 165432b31808SJens Wiklander } 1655817466cbSJens Wiklander 165632b31808SJens Wiklander if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { 16573d3b0591SJens Wiklander goto exit; 165832b31808SJens Wiklander } 165932b31808SJens Wiklander if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) { 16603d3b0591SJens Wiklander goto exit; 166132b31808SJens Wiklander } 166232b31808SJens Wiklander if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) { 16633d3b0591SJens Wiklander goto exit; 166432b31808SJens Wiklander } 166532b31808SJens Wiklander if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) { 16663d3b0591SJens Wiklander goto exit; 166732b31808SJens Wiklander } 1668817466cbSJens Wiklander 166932b31808SJens Wiklander for (i = 0; i < use_len; ++i) { 1670817466cbSJens Wiklander *p++ ^= mask[i]; 167132b31808SJens Wiklander } 1672817466cbSJens Wiklander 1673817466cbSJens Wiklander counter[3]++; 1674817466cbSJens Wiklander 1675817466cbSJens Wiklander dlen -= use_len; 1676817466cbSJens Wiklander } 1677817466cbSJens Wiklander 16783d3b0591SJens Wiklander exit: 16793d3b0591SJens Wiklander mbedtls_platform_zeroize(mask, sizeof(mask)); 168032b31808SJens Wiklander mbedtls_md_free(&md_ctx); 16813d3b0591SJens Wiklander 168232b31808SJens Wiklander return ret; 168332b31808SJens Wiklander } 168432b31808SJens Wiklander 168532b31808SJens Wiklander /** 168632b31808SJens Wiklander * Generate Hash(M') as in RFC 8017 page 43 points 5 and 6. 168732b31808SJens Wiklander * 168832b31808SJens Wiklander * \param hash the input hash 168932b31808SJens Wiklander * \param hlen length of the input hash 169032b31808SJens Wiklander * \param salt the input salt 169132b31808SJens Wiklander * \param slen length of the input salt 169232b31808SJens Wiklander * \param out the output buffer - must be large enough for \p md_alg 169332b31808SJens Wiklander * \param md_alg message digest to use 169432b31808SJens Wiklander */ 169532b31808SJens Wiklander static int hash_mprime(const unsigned char *hash, size_t hlen, 169632b31808SJens Wiklander const unsigned char *salt, size_t slen, 169732b31808SJens Wiklander unsigned char *out, mbedtls_md_type_t md_alg) 169832b31808SJens Wiklander { 169932b31808SJens Wiklander const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 170032b31808SJens Wiklander 170132b31808SJens Wiklander mbedtls_md_context_t md_ctx; 170232b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 170332b31808SJens Wiklander 170432b31808SJens Wiklander const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); 170532b31808SJens Wiklander if (md_info == NULL) { 170632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 170732b31808SJens Wiklander } 170832b31808SJens Wiklander 170932b31808SJens Wiklander mbedtls_md_init(&md_ctx); 171032b31808SJens Wiklander if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { 171132b31808SJens Wiklander goto exit; 171232b31808SJens Wiklander } 171332b31808SJens Wiklander if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { 171432b31808SJens Wiklander goto exit; 171532b31808SJens Wiklander } 171632b31808SJens Wiklander if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) { 171732b31808SJens Wiklander goto exit; 171832b31808SJens Wiklander } 171932b31808SJens Wiklander if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) { 172032b31808SJens Wiklander goto exit; 172132b31808SJens Wiklander } 172232b31808SJens Wiklander if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) { 172332b31808SJens Wiklander goto exit; 172432b31808SJens Wiklander } 172532b31808SJens Wiklander if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) { 172632b31808SJens Wiklander goto exit; 172732b31808SJens Wiklander } 172832b31808SJens Wiklander 172932b31808SJens Wiklander exit: 173032b31808SJens Wiklander mbedtls_md_free(&md_ctx); 173132b31808SJens Wiklander 173232b31808SJens Wiklander return ret; 173332b31808SJens Wiklander } 173432b31808SJens Wiklander 173532b31808SJens Wiklander /** 173632b31808SJens Wiklander * Compute a hash. 173732b31808SJens Wiklander * 173832b31808SJens Wiklander * \param md_alg algorithm to use 173932b31808SJens Wiklander * \param input input message to hash 174032b31808SJens Wiklander * \param ilen input length 174132b31808SJens Wiklander * \param output the output buffer - must be large enough for \p md_alg 174232b31808SJens Wiklander */ 174332b31808SJens Wiklander static int compute_hash(mbedtls_md_type_t md_alg, 174432b31808SJens Wiklander const unsigned char *input, size_t ilen, 174532b31808SJens Wiklander unsigned char *output) 174632b31808SJens Wiklander { 174732b31808SJens Wiklander const mbedtls_md_info_t *md_info; 174832b31808SJens Wiklander 174932b31808SJens Wiklander md_info = mbedtls_md_info_from_type(md_alg); 175032b31808SJens Wiklander if (md_info == NULL) { 175132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 175232b31808SJens Wiklander } 175332b31808SJens Wiklander 175432b31808SJens Wiklander return mbedtls_md(md_info, input, ilen, output); 1755817466cbSJens Wiklander } 1756817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 1757817466cbSJens Wiklander 1758817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 1759817466cbSJens Wiklander /* 1760817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function 1761817466cbSJens Wiklander */ 1762817466cbSJens Wiklander int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, 1763817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1764817466cbSJens Wiklander void *p_rng, 1765817466cbSJens Wiklander const unsigned char *label, size_t label_len, 1766817466cbSJens Wiklander size_t ilen, 1767817466cbSJens Wiklander const unsigned char *input, 1768817466cbSJens Wiklander unsigned char *output) 1769817466cbSJens Wiklander { 1770817466cbSJens Wiklander size_t olen; 177111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1772817466cbSJens Wiklander unsigned char *p = output; 1773817466cbSJens Wiklander unsigned int hlen; 1774817466cbSJens Wiklander 177532b31808SJens Wiklander if (f_rng == NULL) { 177632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 177732b31808SJens Wiklander } 17783d3b0591SJens Wiklander 1779*b0563631STom Van Eyck hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id); 178032b31808SJens Wiklander if (hlen == 0) { 178132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 178232b31808SJens Wiklander } 1783817466cbSJens Wiklander 1784817466cbSJens Wiklander olen = ctx->len; 1785817466cbSJens Wiklander 1786817466cbSJens Wiklander /* first comparison checks for overflow */ 178732b31808SJens Wiklander if (ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2) { 178832b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 178932b31808SJens Wiklander } 1790817466cbSJens Wiklander 1791817466cbSJens Wiklander memset(output, 0, olen); 1792817466cbSJens Wiklander 1793817466cbSJens Wiklander *p++ = 0; 1794817466cbSJens Wiklander 1795817466cbSJens Wiklander /* Generate a random octet string seed */ 179632b31808SJens Wiklander if ((ret = f_rng(p_rng, p, hlen)) != 0) { 179732b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); 179832b31808SJens Wiklander } 1799817466cbSJens Wiklander 1800817466cbSJens Wiklander p += hlen; 1801817466cbSJens Wiklander 1802817466cbSJens Wiklander /* Construct DB */ 180332b31808SJens Wiklander ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, label, label_len, p); 180432b31808SJens Wiklander if (ret != 0) { 180532b31808SJens Wiklander return ret; 180632b31808SJens Wiklander } 1807817466cbSJens Wiklander p += hlen; 1808817466cbSJens Wiklander p += olen - 2 * hlen - 2 - ilen; 1809817466cbSJens Wiklander *p++ = 1; 181032b31808SJens Wiklander if (ilen != 0) { 1811817466cbSJens Wiklander memcpy(p, input, ilen); 181232b31808SJens Wiklander } 1813817466cbSJens Wiklander 1814817466cbSJens Wiklander /* maskedDB: Apply dbMask to DB */ 18153d3b0591SJens Wiklander if ((ret = mgf_mask(output + hlen + 1, olen - hlen - 1, output + 1, hlen, 1816*b0563631STom Van Eyck (mbedtls_md_type_t) ctx->hash_id)) != 0) { 181732b31808SJens Wiklander return ret; 181832b31808SJens Wiklander } 1819817466cbSJens Wiklander 1820817466cbSJens Wiklander /* maskedSeed: Apply seedMask to seed */ 18213d3b0591SJens Wiklander if ((ret = mgf_mask(output + 1, hlen, output + hlen + 1, olen - hlen - 1, 1822*b0563631STom Van Eyck (mbedtls_md_type_t) ctx->hash_id)) != 0) { 182332b31808SJens Wiklander return ret; 182432b31808SJens Wiklander } 1825817466cbSJens Wiklander 182632b31808SJens Wiklander return mbedtls_rsa_public(ctx, output, output); 1827817466cbSJens Wiklander } 1828817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 1829817466cbSJens Wiklander 1830817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 1831817466cbSJens Wiklander /* 1832817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function 1833817466cbSJens Wiklander */ 1834817466cbSJens Wiklander int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx, 1835817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 183632b31808SJens Wiklander void *p_rng, size_t ilen, 1837817466cbSJens Wiklander const unsigned char *input, 1838817466cbSJens Wiklander unsigned char *output) 1839817466cbSJens Wiklander { 1840817466cbSJens Wiklander size_t nb_pad, olen; 184111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1842817466cbSJens Wiklander unsigned char *p = output; 1843817466cbSJens Wiklander 1844817466cbSJens Wiklander olen = ctx->len; 1845817466cbSJens Wiklander 1846817466cbSJens Wiklander /* first comparison checks for overflow */ 184732b31808SJens Wiklander if (ilen + 11 < ilen || olen < ilen + 11) { 184832b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 184932b31808SJens Wiklander } 1850817466cbSJens Wiklander 1851817466cbSJens Wiklander nb_pad = olen - 3 - ilen; 1852817466cbSJens Wiklander 1853817466cbSJens Wiklander *p++ = 0; 185432b31808SJens Wiklander 185532b31808SJens Wiklander if (f_rng == NULL) { 185632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 185732b31808SJens Wiklander } 18583d3b0591SJens Wiklander 1859817466cbSJens Wiklander *p++ = MBEDTLS_RSA_CRYPT; 1860817466cbSJens Wiklander 186132b31808SJens Wiklander while (nb_pad-- > 0) { 1862817466cbSJens Wiklander int rng_dl = 100; 1863817466cbSJens Wiklander 1864817466cbSJens Wiklander do { 1865817466cbSJens Wiklander ret = f_rng(p_rng, p, 1); 1866817466cbSJens Wiklander } while (*p == 0 && --rng_dl && ret == 0); 1867817466cbSJens Wiklander 1868817466cbSJens Wiklander /* Check if RNG failed to generate data */ 186932b31808SJens Wiklander if (rng_dl == 0 || ret != 0) { 187032b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); 187132b31808SJens Wiklander } 1872817466cbSJens Wiklander 1873817466cbSJens Wiklander p++; 1874817466cbSJens Wiklander } 1875817466cbSJens Wiklander 1876817466cbSJens Wiklander *p++ = 0; 187732b31808SJens Wiklander if (ilen != 0) { 1878817466cbSJens Wiklander memcpy(p, input, ilen); 187932b31808SJens Wiklander } 1880817466cbSJens Wiklander 188132b31808SJens Wiklander return mbedtls_rsa_public(ctx, output, output); 1882817466cbSJens Wiklander } 1883817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 1884817466cbSJens Wiklander 1885817466cbSJens Wiklander /* 1886817466cbSJens Wiklander * Add the message padding, then do an RSA operation 1887817466cbSJens Wiklander */ 1888817466cbSJens Wiklander int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx, 1889817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1890817466cbSJens Wiklander void *p_rng, 189132b31808SJens Wiklander size_t ilen, 1892817466cbSJens Wiklander const unsigned char *input, 1893817466cbSJens Wiklander unsigned char *output) 1894817466cbSJens Wiklander { 189532b31808SJens Wiklander switch (ctx->padding) { 1896817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 1897817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V15: 189832b31808SJens Wiklander return mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx, f_rng, p_rng, 189932b31808SJens Wiklander ilen, input, output); 1900817466cbSJens Wiklander #endif 1901817466cbSJens Wiklander 1902817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 1903817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V21: 190432b31808SJens Wiklander return mbedtls_rsa_rsaes_oaep_encrypt(ctx, f_rng, p_rng, NULL, 0, 1905817466cbSJens Wiklander ilen, input, output); 1906817466cbSJens Wiklander #endif 1907817466cbSJens Wiklander 1908817466cbSJens Wiklander default: 190932b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 1910817466cbSJens Wiklander } 1911817466cbSJens Wiklander } 1912817466cbSJens Wiklander 1913817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 1914817466cbSJens Wiklander /* 1915817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function 1916817466cbSJens Wiklander */ 1917817466cbSJens Wiklander int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx, 1918817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1919817466cbSJens Wiklander void *p_rng, 1920817466cbSJens Wiklander const unsigned char *label, size_t label_len, 1921817466cbSJens Wiklander size_t *olen, 1922817466cbSJens Wiklander const unsigned char *input, 1923817466cbSJens Wiklander unsigned char *output, 1924817466cbSJens Wiklander size_t output_max_len) 1925817466cbSJens Wiklander { 192611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1927817466cbSJens Wiklander size_t ilen, i, pad_len; 1928*b0563631STom Van Eyck unsigned char *p; 1929*b0563631STom Van Eyck mbedtls_ct_condition_t bad, in_padding; 1930817466cbSJens Wiklander unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; 1931*b0563631STom Van Eyck unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; 1932817466cbSJens Wiklander unsigned int hlen; 19333d3b0591SJens Wiklander 1934817466cbSJens Wiklander /* 1935817466cbSJens Wiklander * Parameters sanity checks 1936817466cbSJens Wiklander */ 193732b31808SJens Wiklander if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { 193832b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 193932b31808SJens Wiklander } 1940817466cbSJens Wiklander 1941817466cbSJens Wiklander ilen = ctx->len; 1942817466cbSJens Wiklander 194332b31808SJens Wiklander if (ilen < 16 || ilen > sizeof(buf)) { 194432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 194532b31808SJens Wiklander } 1946817466cbSJens Wiklander 1947*b0563631STom Van Eyck hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id); 194832b31808SJens Wiklander if (hlen == 0) { 194932b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 195032b31808SJens Wiklander } 1951817466cbSJens Wiklander 1952817466cbSJens Wiklander // checking for integer underflow 195332b31808SJens Wiklander if (2 * hlen + 2 > ilen) { 195432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 195532b31808SJens Wiklander } 1956817466cbSJens Wiklander 1957817466cbSJens Wiklander /* 1958817466cbSJens Wiklander * RSA operation 1959817466cbSJens Wiklander */ 19608452b181SSummer Qin if( ctx->P.n == 0 ) 196132b31808SJens Wiklander ret = mbedtls_rsa_private( ctx, NULL, NULL, input, buf ); 19628452b181SSummer Qin else 196332b31808SJens Wiklander ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf); 1964817466cbSJens Wiklander 196532b31808SJens Wiklander if (ret != 0) { 1966817466cbSJens Wiklander goto cleanup; 196732b31808SJens Wiklander } 1968817466cbSJens Wiklander 1969817466cbSJens Wiklander /* 1970817466cbSJens Wiklander * Unmask data and generate lHash 1971817466cbSJens Wiklander */ 1972817466cbSJens Wiklander /* seed: Apply seedMask to maskedSeed */ 19733d3b0591SJens Wiklander if ((ret = mgf_mask(buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, 1974*b0563631STom Van Eyck (mbedtls_md_type_t) ctx->hash_id)) != 0 || 1975817466cbSJens Wiklander /* DB: Apply dbMask to maskedDB */ 19763d3b0591SJens Wiklander (ret = mgf_mask(buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, 1977*b0563631STom Van Eyck (mbedtls_md_type_t) ctx->hash_id)) != 0) { 19783d3b0591SJens Wiklander goto cleanup; 19793d3b0591SJens Wiklander } 1980817466cbSJens Wiklander 19813d3b0591SJens Wiklander /* Generate lHash */ 198232b31808SJens Wiklander ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, 198332b31808SJens Wiklander label, label_len, lhash); 198432b31808SJens Wiklander if (ret != 0) { 19853d3b0591SJens Wiklander goto cleanup; 198632b31808SJens Wiklander } 19873d3b0591SJens Wiklander 1988817466cbSJens Wiklander /* 1989817466cbSJens Wiklander * Check contents, in "constant-time" 1990817466cbSJens Wiklander */ 1991817466cbSJens Wiklander p = buf; 1992817466cbSJens Wiklander 1993*b0563631STom Van Eyck bad = mbedtls_ct_bool(*p++); /* First byte must be 0 */ 1994817466cbSJens Wiklander 1995817466cbSJens Wiklander p += hlen; /* Skip seed */ 1996817466cbSJens Wiklander 1997817466cbSJens Wiklander /* Check lHash */ 1998*b0563631STom Van Eyck bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool(mbedtls_ct_memcmp(lhash, p, hlen))); 1999*b0563631STom Van Eyck p += hlen; 2000817466cbSJens Wiklander 2001817466cbSJens Wiklander /* Get zero-padding len, but always read till end of buffer 2002817466cbSJens Wiklander * (minus one, for the 01 byte) */ 2003817466cbSJens Wiklander pad_len = 0; 2004*b0563631STom Van Eyck in_padding = MBEDTLS_CT_TRUE; 200532b31808SJens Wiklander for (i = 0; i < ilen - 2 * hlen - 2; i++) { 2006*b0563631STom Van Eyck in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_uint_eq(p[i], 0)); 2007*b0563631STom Van Eyck pad_len += mbedtls_ct_uint_if_else_0(in_padding, 1); 2008817466cbSJens Wiklander } 2009817466cbSJens Wiklander 2010817466cbSJens Wiklander p += pad_len; 2011*b0563631STom Van Eyck bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(*p++, 0x01)); 2012817466cbSJens Wiklander 2013817466cbSJens Wiklander /* 2014817466cbSJens Wiklander * The only information "leaked" is whether the padding was correct or not 2015817466cbSJens Wiklander * (eg, no data is copied if it was not correct). This meets the 2016817466cbSJens Wiklander * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between 2017817466cbSJens Wiklander * the different error conditions. 2018817466cbSJens Wiklander */ 2019*b0563631STom Van Eyck if (bad != MBEDTLS_CT_FALSE) { 2020817466cbSJens Wiklander ret = MBEDTLS_ERR_RSA_INVALID_PADDING; 2021817466cbSJens Wiklander goto cleanup; 2022817466cbSJens Wiklander } 2023817466cbSJens Wiklander 2024*b0563631STom Van Eyck if (ilen - ((size_t) (p - buf)) > output_max_len) { 2025817466cbSJens Wiklander ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; 2026817466cbSJens Wiklander goto cleanup; 2027817466cbSJens Wiklander } 2028817466cbSJens Wiklander 2029*b0563631STom Van Eyck *olen = ilen - ((size_t) (p - buf)); 203032b31808SJens Wiklander if (*olen != 0) { 2031817466cbSJens Wiklander memcpy(output, p, *olen); 203232b31808SJens Wiklander } 2033817466cbSJens Wiklander ret = 0; 2034817466cbSJens Wiklander 2035817466cbSJens Wiklander cleanup: 20363d3b0591SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 20373d3b0591SJens Wiklander mbedtls_platform_zeroize(lhash, sizeof(lhash)); 2038817466cbSJens Wiklander 203932b31808SJens Wiklander return ret; 2040817466cbSJens Wiklander } 2041817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 2042817466cbSJens Wiklander 2043817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2044817466cbSJens Wiklander /* 2045817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function 2046817466cbSJens Wiklander */ 2047817466cbSJens Wiklander int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx, 2048817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 2049817466cbSJens Wiklander void *p_rng, 2050039e02dfSJerome Forissier size_t *olen, 2051817466cbSJens Wiklander const unsigned char *input, 2052817466cbSJens Wiklander unsigned char *output, 2053817466cbSJens Wiklander size_t output_max_len) 2054817466cbSJens Wiklander { 205511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2056039e02dfSJerome Forissier size_t ilen; 2057817466cbSJens Wiklander unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; 20583d3b0591SJens Wiklander 20593d3b0591SJens Wiklander ilen = ctx->len; 2060817466cbSJens Wiklander 206132b31808SJens Wiklander if (ctx->padding != MBEDTLS_RSA_PKCS_V15) { 206232b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 206332b31808SJens Wiklander } 2064817466cbSJens Wiklander 206532b31808SJens Wiklander if (ilen < 16 || ilen > sizeof(buf)) { 206632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 206732b31808SJens Wiklander } 2068817466cbSJens Wiklander 206932b31808SJens Wiklander ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf); 2070817466cbSJens Wiklander 207132b31808SJens Wiklander if (ret != 0) { 2072817466cbSJens Wiklander goto cleanup; 207332b31808SJens Wiklander } 2074817466cbSJens Wiklander 207532b31808SJens Wiklander ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding(buf, ilen, 2076039e02dfSJerome Forissier output, output_max_len, olen); 2077817466cbSJens Wiklander 2078817466cbSJens Wiklander cleanup: 20793d3b0591SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 2080817466cbSJens Wiklander 208132b31808SJens Wiklander return ret; 2082817466cbSJens Wiklander } 2083817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 2084817466cbSJens Wiklander 2085817466cbSJens Wiklander /* 2086817466cbSJens Wiklander * Do an RSA operation, then remove the message padding 2087817466cbSJens Wiklander */ 2088817466cbSJens Wiklander int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, 2089817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 2090817466cbSJens Wiklander void *p_rng, 209132b31808SJens Wiklander size_t *olen, 2092817466cbSJens Wiklander const unsigned char *input, 2093817466cbSJens Wiklander unsigned char *output, 2094817466cbSJens Wiklander size_t output_max_len) 2095817466cbSJens Wiklander { 209632b31808SJens Wiklander switch (ctx->padding) { 2097817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2098817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V15: 209932b31808SJens Wiklander return mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx, f_rng, p_rng, olen, 2100817466cbSJens Wiklander input, output, output_max_len); 2101817466cbSJens Wiklander #endif 2102817466cbSJens Wiklander 2103817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 2104817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V21: 210532b31808SJens Wiklander return mbedtls_rsa_rsaes_oaep_decrypt(ctx, f_rng, p_rng, NULL, 0, 2106817466cbSJens Wiklander olen, input, output, 2107817466cbSJens Wiklander output_max_len); 2108817466cbSJens Wiklander #endif 2109817466cbSJens Wiklander 2110817466cbSJens Wiklander default: 211132b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2112817466cbSJens Wiklander } 2113817466cbSJens Wiklander } 2114817466cbSJens Wiklander 2115817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 2116*b0563631STom Van Eyck static int rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, 2117817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 2118817466cbSJens Wiklander void *p_rng, 2119817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2120817466cbSJens Wiklander unsigned int hashlen, 2121817466cbSJens Wiklander const unsigned char *hash, 21227901324dSJerome Forissier int saltlen, 2123817466cbSJens Wiklander unsigned char *sig) 2124817466cbSJens Wiklander { 2125817466cbSJens Wiklander size_t olen; 2126817466cbSJens Wiklander unsigned char *p = sig; 21277901324dSJerome Forissier unsigned char *salt = NULL; 21283d3b0591SJens Wiklander size_t slen, min_slen, hlen, offset = 0; 212911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2130817466cbSJens Wiklander size_t msb; 2131*b0563631STom Van Eyck mbedtls_md_type_t hash_id; 2132817466cbSJens Wiklander 213332b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 213432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 213532b31808SJens Wiklander } 2136817466cbSJens Wiklander 213732b31808SJens Wiklander if (f_rng == NULL) { 213832b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 213932b31808SJens Wiklander } 2140817466cbSJens Wiklander 2141817466cbSJens Wiklander olen = ctx->len; 2142817466cbSJens Wiklander 214332b31808SJens Wiklander if (md_alg != MBEDTLS_MD_NONE) { 2144817466cbSJens Wiklander /* Gather length of hash to sign */ 2145*b0563631STom Van Eyck size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); 214632b31808SJens Wiklander if (exp_hashlen == 0) { 214732b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 2148817466cbSJens Wiklander } 2149817466cbSJens Wiklander 215032b31808SJens Wiklander if (hashlen != exp_hashlen) { 215132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 215232b31808SJens Wiklander } 215332b31808SJens Wiklander } 2154817466cbSJens Wiklander 2155*b0563631STom Van Eyck hash_id = (mbedtls_md_type_t) ctx->hash_id; 2156*b0563631STom Van Eyck if (hash_id == MBEDTLS_MD_NONE) { 2157*b0563631STom Van Eyck hash_id = md_alg; 2158*b0563631STom Van Eyck } 2159*b0563631STom Van Eyck hlen = mbedtls_md_get_size_from_type(hash_id); 216032b31808SJens Wiklander if (hlen == 0) { 216132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 216232b31808SJens Wiklander } 2163817466cbSJens Wiklander 216432b31808SJens Wiklander if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) { 21657901324dSJerome Forissier /* Calculate the largest possible salt length, up to the hash size. 21667901324dSJerome Forissier * Normally this is the hash length, which is the maximum salt length 21677901324dSJerome Forissier * according to FIPS 185-4 §5.5 (e) and common practice. If there is not 21683d3b0591SJens Wiklander * enough room, use the maximum salt length that fits. The constraint is 21693d3b0591SJens Wiklander * that the hash length plus the salt length plus 2 bytes must be at most 21703d3b0591SJens Wiklander * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 21713d3b0591SJens Wiklander * (PKCS#1 v2.2) §9.1.1 step 3. */ 21723d3b0591SJens Wiklander min_slen = hlen - 2; 217332b31808SJens Wiklander if (olen < hlen + min_slen + 2) { 217432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 217532b31808SJens Wiklander } else if (olen >= hlen + hlen + 2) { 21763d3b0591SJens Wiklander slen = hlen; 217732b31808SJens Wiklander } else { 21783d3b0591SJens Wiklander slen = olen - hlen - 2; 21797901324dSJerome Forissier } 218032b31808SJens Wiklander } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) { 218132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 218232b31808SJens Wiklander } else { 21837901324dSJerome Forissier slen = (size_t) saltlen; 21847901324dSJerome Forissier } 2185817466cbSJens Wiklander 2186817466cbSJens Wiklander memset(sig, 0, olen); 2187817466cbSJens Wiklander 2188817466cbSJens Wiklander /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ 2189817466cbSJens Wiklander msb = mbedtls_mpi_bitlen(&ctx->N) - 1; 21903d3b0591SJens Wiklander p += olen - hlen - slen - 2; 2191817466cbSJens Wiklander *p++ = 0x01; 21927901324dSJerome Forissier 21937901324dSJerome Forissier /* Generate salt of length slen in place in the encoded message */ 21947901324dSJerome Forissier salt = p; 219532b31808SJens Wiklander if ((ret = f_rng(p_rng, salt, slen)) != 0) { 219632b31808SJens Wiklander return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); 219732b31808SJens Wiklander } 21987901324dSJerome Forissier 2199817466cbSJens Wiklander p += slen; 2200817466cbSJens Wiklander 2201817466cbSJens Wiklander /* Generate H = Hash( M' ) */ 2202*b0563631STom Van Eyck ret = hash_mprime(hash, hashlen, salt, slen, p, hash_id); 220332b31808SJens Wiklander if (ret != 0) { 220432b31808SJens Wiklander return ret; 220532b31808SJens Wiklander } 2206817466cbSJens Wiklander 2207817466cbSJens Wiklander /* Compensate for boundary condition when applying mask */ 220832b31808SJens Wiklander if (msb % 8 == 0) { 2209817466cbSJens Wiklander offset = 1; 221032b31808SJens Wiklander } 2211817466cbSJens Wiklander 2212817466cbSJens Wiklander /* maskedDB: Apply dbMask to DB */ 2213*b0563631STom Van Eyck ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_id); 221432b31808SJens Wiklander if (ret != 0) { 221532b31808SJens Wiklander return ret; 221632b31808SJens Wiklander } 2217817466cbSJens Wiklander 2218817466cbSJens Wiklander msb = mbedtls_mpi_bitlen(&ctx->N) - 1; 2219817466cbSJens Wiklander sig[0] &= 0xFF >> (olen * 8 - msb); 2220817466cbSJens Wiklander 2221817466cbSJens Wiklander p += hlen; 2222817466cbSJens Wiklander *p++ = 0xBC; 2223817466cbSJens Wiklander 22248452b181SSummer Qin if (ctx->P.n == 0) 222532b31808SJens Wiklander return mbedtls_rsa_private(ctx, NULL, NULL, sig, sig); 222632b31808SJens Wiklander 222732b31808SJens Wiklander return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig); 2228817466cbSJens Wiklander } 22297901324dSJerome Forissier 2230*b0563631STom Van Eyck static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, 2231*b0563631STom Van Eyck int (*f_rng)(void *, unsigned char *, size_t), 2232*b0563631STom Van Eyck void *p_rng, 2233*b0563631STom Van Eyck mbedtls_md_type_t md_alg, 2234*b0563631STom Van Eyck unsigned int hashlen, 2235*b0563631STom Van Eyck const unsigned char *hash, 2236*b0563631STom Van Eyck int saltlen, 2237*b0563631STom Van Eyck unsigned char *sig) 2238*b0563631STom Van Eyck { 2239*b0563631STom Van Eyck if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { 2240*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 2241*b0563631STom Van Eyck } 2242*b0563631STom Van Eyck if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) { 2243*b0563631STom Van Eyck return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 2244*b0563631STom Van Eyck } 2245*b0563631STom Van Eyck return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen, 2246*b0563631STom Van Eyck sig); 2247*b0563631STom Van Eyck } 2248*b0563631STom Van Eyck 2249*b0563631STom Van Eyck int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, 2250*b0563631STom Van Eyck int (*f_rng)(void *, unsigned char *, size_t), 2251*b0563631STom Van Eyck void *p_rng, 2252*b0563631STom Van Eyck mbedtls_md_type_t md_alg, 2253*b0563631STom Van Eyck unsigned int hashlen, 2254*b0563631STom Van Eyck const unsigned char *hash, 2255*b0563631STom Van Eyck unsigned char *sig) 2256*b0563631STom Van Eyck { 2257*b0563631STom Van Eyck return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, 2258*b0563631STom Van Eyck hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig); 2259*b0563631STom Van Eyck } 2260*b0563631STom Van Eyck 22617901324dSJerome Forissier /* 22627901324dSJerome Forissier * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with 22637901324dSJerome Forissier * the option to pass in the salt length. 22647901324dSJerome Forissier */ 22657901324dSJerome Forissier int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx, 22667901324dSJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), 22677901324dSJerome Forissier void *p_rng, 22687901324dSJerome Forissier mbedtls_md_type_t md_alg, 22697901324dSJerome Forissier unsigned int hashlen, 22707901324dSJerome Forissier const unsigned char *hash, 22717901324dSJerome Forissier int saltlen, 22727901324dSJerome Forissier unsigned char *sig) 22737901324dSJerome Forissier { 227432b31808SJens Wiklander return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, 22757901324dSJerome Forissier hashlen, hash, saltlen, sig); 22767901324dSJerome Forissier } 22777901324dSJerome Forissier 22787901324dSJerome Forissier /* 22797901324dSJerome Forissier * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function 22807901324dSJerome Forissier */ 22817901324dSJerome Forissier int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, 22827901324dSJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), 22837901324dSJerome Forissier void *p_rng, 22847901324dSJerome Forissier mbedtls_md_type_t md_alg, 22857901324dSJerome Forissier unsigned int hashlen, 22867901324dSJerome Forissier const unsigned char *hash, 22877901324dSJerome Forissier unsigned char *sig) 22887901324dSJerome Forissier { 228932b31808SJens Wiklander return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, 22907901324dSJerome Forissier hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig); 22917901324dSJerome Forissier } 2292817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 2293817466cbSJens Wiklander 2294817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2295817466cbSJens Wiklander /* 2296817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function 2297817466cbSJens Wiklander */ 22983d3b0591SJens Wiklander 22993d3b0591SJens Wiklander /* Construct a PKCS v1.5 encoding of a hashed message 23003d3b0591SJens Wiklander * 23013d3b0591SJens Wiklander * This is used both for signature generation and verification. 23023d3b0591SJens Wiklander * 23033d3b0591SJens Wiklander * Parameters: 23043d3b0591SJens Wiklander * - md_alg: Identifies the hash algorithm used to generate the given hash; 23053d3b0591SJens Wiklander * MBEDTLS_MD_NONE if raw data is signed. 230632b31808SJens Wiklander * - hashlen: Length of hash. Must match md_alg if that's not NONE. 23073d3b0591SJens Wiklander * - hash: Buffer containing the hashed message or the raw data. 23083d3b0591SJens Wiklander * - dst_len: Length of the encoded message. 23093d3b0591SJens Wiklander * - dst: Buffer to hold the encoded message. 23103d3b0591SJens Wiklander * 23113d3b0591SJens Wiklander * Assumptions: 231232b31808SJens Wiklander * - hash has size hashlen. 23133d3b0591SJens Wiklander * - dst points to a buffer of size at least dst_len. 23143d3b0591SJens Wiklander * 23153d3b0591SJens Wiklander */ 23163d3b0591SJens Wiklander static int rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg, 23173d3b0591SJens Wiklander unsigned int hashlen, 23183d3b0591SJens Wiklander const unsigned char *hash, 23193d3b0591SJens Wiklander size_t dst_len, 23203d3b0591SJens Wiklander unsigned char *dst) 23213d3b0591SJens Wiklander { 23223d3b0591SJens Wiklander size_t oid_size = 0; 23233d3b0591SJens Wiklander size_t nb_pad = dst_len; 23243d3b0591SJens Wiklander unsigned char *p = dst; 23253d3b0591SJens Wiklander const char *oid = NULL; 23263d3b0591SJens Wiklander 23273d3b0591SJens Wiklander /* Are we signing hashed or raw data? */ 232832b31808SJens Wiklander if (md_alg != MBEDTLS_MD_NONE) { 2329*b0563631STom Van Eyck unsigned char md_size = mbedtls_md_get_size_from_type(md_alg); 233032b31808SJens Wiklander if (md_size == 0) { 233132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 233232b31808SJens Wiklander } 23333d3b0591SJens Wiklander 233432b31808SJens Wiklander if (mbedtls_oid_get_oid_by_md(md_alg, &oid, &oid_size) != 0) { 233532b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 233632b31808SJens Wiklander } 23373d3b0591SJens Wiklander 233832b31808SJens Wiklander if (hashlen != md_size) { 233932b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 234032b31808SJens Wiklander } 23413d3b0591SJens Wiklander 23423d3b0591SJens Wiklander /* Double-check that 8 + hashlen + oid_size can be used as a 23433d3b0591SJens Wiklander * 1-byte ASN.1 length encoding and that there's no overflow. */ 23443d3b0591SJens Wiklander if (8 + hashlen + oid_size >= 0x80 || 23453d3b0591SJens Wiklander 10 + hashlen < hashlen || 234632b31808SJens Wiklander 10 + hashlen + oid_size < 10 + hashlen) { 234732b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 234832b31808SJens Wiklander } 23493d3b0591SJens Wiklander 23503d3b0591SJens Wiklander /* 23513d3b0591SJens Wiklander * Static bounds check: 23523d3b0591SJens Wiklander * - Need 10 bytes for five tag-length pairs. 23533d3b0591SJens Wiklander * (Insist on 1-byte length encodings to protect against variants of 23543d3b0591SJens Wiklander * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) 23553d3b0591SJens Wiklander * - Need hashlen bytes for hash 23563d3b0591SJens Wiklander * - Need oid_size bytes for hash alg OID. 23573d3b0591SJens Wiklander */ 235832b31808SJens Wiklander if (nb_pad < 10 + hashlen + oid_size) { 235932b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 23603d3b0591SJens Wiklander } 236132b31808SJens Wiklander nb_pad -= 10 + hashlen + oid_size; 236232b31808SJens Wiklander } else { 236332b31808SJens Wiklander if (nb_pad < hashlen) { 236432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 236532b31808SJens Wiklander } 23663d3b0591SJens Wiklander 23673d3b0591SJens Wiklander nb_pad -= hashlen; 23683d3b0591SJens Wiklander } 23693d3b0591SJens Wiklander 23703d3b0591SJens Wiklander /* Need space for signature header and padding delimiter (3 bytes), 23713d3b0591SJens Wiklander * and 8 bytes for the minimal padding */ 237232b31808SJens Wiklander if (nb_pad < 3 + 8) { 237332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 237432b31808SJens Wiklander } 23753d3b0591SJens Wiklander nb_pad -= 3; 23763d3b0591SJens Wiklander 23773d3b0591SJens Wiklander /* Now nb_pad is the amount of memory to be filled 23783d3b0591SJens Wiklander * with padding, and at least 8 bytes long. */ 23793d3b0591SJens Wiklander 23803d3b0591SJens Wiklander /* Write signature header and padding */ 23813d3b0591SJens Wiklander *p++ = 0; 23823d3b0591SJens Wiklander *p++ = MBEDTLS_RSA_SIGN; 23833d3b0591SJens Wiklander memset(p, 0xFF, nb_pad); 23843d3b0591SJens Wiklander p += nb_pad; 23853d3b0591SJens Wiklander *p++ = 0; 23863d3b0591SJens Wiklander 23873d3b0591SJens Wiklander /* Are we signing raw data? */ 238832b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE) { 23893d3b0591SJens Wiklander memcpy(p, hash, hashlen); 239032b31808SJens Wiklander return 0; 23913d3b0591SJens Wiklander } 23923d3b0591SJens Wiklander 23933d3b0591SJens Wiklander /* Signing hashed data, add corresponding ASN.1 structure 23943d3b0591SJens Wiklander * 23953d3b0591SJens Wiklander * DigestInfo ::= SEQUENCE { 23963d3b0591SJens Wiklander * digestAlgorithm DigestAlgorithmIdentifier, 23973d3b0591SJens Wiklander * digest Digest } 23983d3b0591SJens Wiklander * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 23993d3b0591SJens Wiklander * Digest ::= OCTET STRING 24003d3b0591SJens Wiklander * 24013d3b0591SJens Wiklander * Schematic: 24023d3b0591SJens Wiklander * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] 24033d3b0591SJens Wiklander * TAG-NULL + LEN [ NULL ] ] 24043d3b0591SJens Wiklander * TAG-OCTET + LEN [ HASH ] ] 24053d3b0591SJens Wiklander */ 24063d3b0591SJens Wiklander *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; 24073d3b0591SJens Wiklander *p++ = (unsigned char) (0x08 + oid_size + hashlen); 24083d3b0591SJens Wiklander *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; 24093d3b0591SJens Wiklander *p++ = (unsigned char) (0x04 + oid_size); 24103d3b0591SJens Wiklander *p++ = MBEDTLS_ASN1_OID; 24113d3b0591SJens Wiklander *p++ = (unsigned char) oid_size; 24123d3b0591SJens Wiklander memcpy(p, oid, oid_size); 24133d3b0591SJens Wiklander p += oid_size; 24143d3b0591SJens Wiklander *p++ = MBEDTLS_ASN1_NULL; 24153d3b0591SJens Wiklander *p++ = 0x00; 24163d3b0591SJens Wiklander *p++ = MBEDTLS_ASN1_OCTET_STRING; 24173d3b0591SJens Wiklander *p++ = (unsigned char) hashlen; 24183d3b0591SJens Wiklander memcpy(p, hash, hashlen); 24193d3b0591SJens Wiklander p += hashlen; 24203d3b0591SJens Wiklander 24213d3b0591SJens Wiklander /* Just a sanity-check, should be automatic 24223d3b0591SJens Wiklander * after the initial bounds check. */ 242332b31808SJens Wiklander if (p != dst + dst_len) { 24243d3b0591SJens Wiklander mbedtls_platform_zeroize(dst, dst_len); 242532b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 24263d3b0591SJens Wiklander } 24273d3b0591SJens Wiklander 242832b31808SJens Wiklander return 0; 24293d3b0591SJens Wiklander } 24303d3b0591SJens Wiklander 2431817466cbSJens Wiklander /* 2432817466cbSJens Wiklander * Do an RSA operation to sign the message digest 2433817466cbSJens Wiklander */ 2434817466cbSJens Wiklander int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx, 2435817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 2436817466cbSJens Wiklander void *p_rng, 2437817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2438817466cbSJens Wiklander unsigned int hashlen, 2439817466cbSJens Wiklander const unsigned char *hash, 2440817466cbSJens Wiklander unsigned char *sig) 2441817466cbSJens Wiklander { 244211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 24433d3b0591SJens Wiklander unsigned char *sig_try = NULL, *verif = NULL; 24443d3b0591SJens Wiklander 244532b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 244632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 244732b31808SJens Wiklander } 2448817466cbSJens Wiklander 244932b31808SJens Wiklander if (ctx->padding != MBEDTLS_RSA_PKCS_V15) { 245032b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 245132b31808SJens Wiklander } 2452817466cbSJens Wiklander 2453817466cbSJens Wiklander /* 24543d3b0591SJens Wiklander * Prepare PKCS1-v1.5 encoding (padding and hash identifier) 2455817466cbSJens Wiklander */ 24563d3b0591SJens Wiklander 24573d3b0591SJens Wiklander if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, 245832b31808SJens Wiklander ctx->len, sig)) != 0) { 245932b31808SJens Wiklander return ret; 24603d3b0591SJens Wiklander } 2461817466cbSJens Wiklander 24623d3b0591SJens Wiklander /* Private key operation 24633d3b0591SJens Wiklander * 2464817466cbSJens Wiklander * In order to prevent Lenstra's attack, make the signature in a 2465817466cbSJens Wiklander * temporary buffer and check it before returning it. 2466817466cbSJens Wiklander */ 24673d3b0591SJens Wiklander 2468817466cbSJens Wiklander sig_try = mbedtls_calloc(1, ctx->len); 246932b31808SJens Wiklander if (sig_try == NULL) { 247032b31808SJens Wiklander return MBEDTLS_ERR_MPI_ALLOC_FAILED; 247132b31808SJens Wiklander } 2472817466cbSJens Wiklander 2473817466cbSJens Wiklander verif = mbedtls_calloc(1, ctx->len); 247432b31808SJens Wiklander if (verif == NULL) { 2475817466cbSJens Wiklander mbedtls_free(sig_try); 247632b31808SJens Wiklander return MBEDTLS_ERR_MPI_ALLOC_FAILED; 2477817466cbSJens Wiklander } 2478817466cbSJens Wiklander 2479817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig_try)); 2480817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_public(ctx, sig_try, verif)); 2481817466cbSJens Wiklander 248232b31808SJens Wiklander if (mbedtls_ct_memcmp(verif, sig, ctx->len) != 0) { 2483817466cbSJens Wiklander ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; 2484817466cbSJens Wiklander goto cleanup; 2485817466cbSJens Wiklander } 2486817466cbSJens Wiklander 2487817466cbSJens Wiklander memcpy(sig, sig_try, ctx->len); 2488817466cbSJens Wiklander 2489817466cbSJens Wiklander cleanup: 2490*b0563631STom Van Eyck mbedtls_zeroize_and_free(sig_try, ctx->len); 2491*b0563631STom Van Eyck mbedtls_zeroize_and_free(verif, ctx->len); 2492817466cbSJens Wiklander 249332b31808SJens Wiklander if (ret != 0) { 2494039e02dfSJerome Forissier memset(sig, '!', ctx->len); 249532b31808SJens Wiklander } 249632b31808SJens Wiklander return ret; 2497817466cbSJens Wiklander } 2498817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 2499817466cbSJens Wiklander 2500817466cbSJens Wiklander /* 2501817466cbSJens Wiklander * Do an RSA operation to sign the message digest 2502817466cbSJens Wiklander */ 2503817466cbSJens Wiklander int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx, 2504817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 2505817466cbSJens Wiklander void *p_rng, 2506817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2507817466cbSJens Wiklander unsigned int hashlen, 2508817466cbSJens Wiklander const unsigned char *hash, 2509817466cbSJens Wiklander unsigned char *sig) 2510817466cbSJens Wiklander { 251132b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 251232b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 251332b31808SJens Wiklander } 25143d3b0591SJens Wiklander 251532b31808SJens Wiklander switch (ctx->padding) { 2516817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2517817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V15: 251832b31808SJens Wiklander return mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx, f_rng, p_rng, 251932b31808SJens Wiklander md_alg, hashlen, hash, sig); 2520817466cbSJens Wiklander #endif 2521817466cbSJens Wiklander 2522817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 2523817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V21: 252432b31808SJens Wiklander return mbedtls_rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, 2525817466cbSJens Wiklander hashlen, hash, sig); 2526817466cbSJens Wiklander #endif 2527817466cbSJens Wiklander 2528817466cbSJens Wiklander default: 252932b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2530817466cbSJens Wiklander } 2531817466cbSJens Wiklander } 2532817466cbSJens Wiklander 2533817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 2534817466cbSJens Wiklander /* 2535817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function 2536817466cbSJens Wiklander */ 2537817466cbSJens Wiklander int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx, 2538817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2539817466cbSJens Wiklander unsigned int hashlen, 2540817466cbSJens Wiklander const unsigned char *hash, 2541817466cbSJens Wiklander mbedtls_md_type_t mgf1_hash_id, 2542817466cbSJens Wiklander int expected_salt_len, 2543817466cbSJens Wiklander const unsigned char *sig) 2544817466cbSJens Wiklander { 254511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2546817466cbSJens Wiklander size_t siglen; 2547817466cbSJens Wiklander unsigned char *p; 25483d3b0591SJens Wiklander unsigned char *hash_start; 2549*b0563631STom Van Eyck unsigned char result[MBEDTLS_MD_MAX_SIZE]; 2550817466cbSJens Wiklander unsigned int hlen; 25513d3b0591SJens Wiklander size_t observed_salt_len, msb; 255232b31808SJens Wiklander unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 }; 2553817466cbSJens Wiklander 255432b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 255532b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 255632b31808SJens Wiklander } 2557817466cbSJens Wiklander 2558817466cbSJens Wiklander siglen = ctx->len; 2559817466cbSJens Wiklander 256032b31808SJens Wiklander if (siglen < 16 || siglen > sizeof(buf)) { 256132b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 256232b31808SJens Wiklander } 2563817466cbSJens Wiklander 256432b31808SJens Wiklander ret = mbedtls_rsa_public(ctx, sig, buf); 2565817466cbSJens Wiklander 256632b31808SJens Wiklander if (ret != 0) { 256732b31808SJens Wiklander return ret; 256832b31808SJens Wiklander } 2569817466cbSJens Wiklander 2570817466cbSJens Wiklander p = buf; 2571817466cbSJens Wiklander 257232b31808SJens Wiklander if (buf[siglen - 1] != 0xBC) { 257332b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2574817466cbSJens Wiklander } 2575817466cbSJens Wiklander 257632b31808SJens Wiklander if (md_alg != MBEDTLS_MD_NONE) { 257732b31808SJens Wiklander /* Gather length of hash to sign */ 2578*b0563631STom Van Eyck size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); 257932b31808SJens Wiklander if (exp_hashlen == 0) { 258032b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 258132b31808SJens Wiklander } 2582817466cbSJens Wiklander 258332b31808SJens Wiklander if (hashlen != exp_hashlen) { 258432b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 258532b31808SJens Wiklander } 258632b31808SJens Wiklander } 2587817466cbSJens Wiklander 2588*b0563631STom Van Eyck hlen = mbedtls_md_get_size_from_type(mgf1_hash_id); 258932b31808SJens Wiklander if (hlen == 0) { 259032b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 259132b31808SJens Wiklander } 2592817466cbSJens Wiklander 2593817466cbSJens Wiklander /* 2594817466cbSJens Wiklander * Note: EMSA-PSS verification is over the length of N - 1 bits 2595817466cbSJens Wiklander */ 2596817466cbSJens Wiklander msb = mbedtls_mpi_bitlen(&ctx->N) - 1; 2597817466cbSJens Wiklander 259832b31808SJens Wiklander if (buf[0] >> (8 - siglen * 8 + msb)) { 259932b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 260032b31808SJens Wiklander } 26013d3b0591SJens Wiklander 2602817466cbSJens Wiklander /* Compensate for boundary condition when applying mask */ 260332b31808SJens Wiklander if (msb % 8 == 0) { 2604817466cbSJens Wiklander p++; 2605817466cbSJens Wiklander siglen -= 1; 2606817466cbSJens Wiklander } 26073d3b0591SJens Wiklander 260832b31808SJens Wiklander if (siglen < hlen + 2) { 260932b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 261032b31808SJens Wiklander } 26113d3b0591SJens Wiklander hash_start = p + siglen - hlen - 1; 2612817466cbSJens Wiklander 261332b31808SJens Wiklander ret = mgf_mask(p, siglen - hlen - 1, hash_start, hlen, mgf1_hash_id); 261432b31808SJens Wiklander if (ret != 0) { 261532b31808SJens Wiklander return ret; 261632b31808SJens Wiklander } 2617817466cbSJens Wiklander 2618817466cbSJens Wiklander buf[0] &= 0xFF >> (siglen * 8 - msb); 2619817466cbSJens Wiklander 262032b31808SJens Wiklander while (p < hash_start - 1 && *p == 0) { 2621817466cbSJens Wiklander p++; 262232b31808SJens Wiklander } 2623817466cbSJens Wiklander 262432b31808SJens Wiklander if (*p++ != 0x01) { 262532b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2626817466cbSJens Wiklander } 2627817466cbSJens Wiklander 2628*b0563631STom Van Eyck observed_salt_len = (size_t) (hash_start - p); 2629817466cbSJens Wiklander 2630817466cbSJens Wiklander if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && 263132b31808SJens Wiklander observed_salt_len != (size_t) expected_salt_len) { 263232b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2633817466cbSJens Wiklander } 2634817466cbSJens Wiklander 2635817466cbSJens Wiklander /* 2636817466cbSJens Wiklander * Generate H = Hash( M' ) 2637817466cbSJens Wiklander */ 263832b31808SJens Wiklander ret = hash_mprime(hash, hashlen, p, observed_salt_len, 263932b31808SJens Wiklander result, mgf1_hash_id); 264032b31808SJens Wiklander if (ret != 0) { 264132b31808SJens Wiklander return ret; 26423d3b0591SJens Wiklander } 26433d3b0591SJens Wiklander 264432b31808SJens Wiklander if (FTMN_CALLEE_DONE_MEMCMP(memcmp, hash_start, result, hlen) != 0) { 264532b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 264632b31808SJens Wiklander } 2647817466cbSJens Wiklander 264832b31808SJens Wiklander return 0; 2649817466cbSJens Wiklander } 2650817466cbSJens Wiklander 2651817466cbSJens Wiklander /* 2652817466cbSJens Wiklander * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function 2653817466cbSJens Wiklander */ 2654817466cbSJens Wiklander int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx, 2655817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2656817466cbSJens Wiklander unsigned int hashlen, 2657817466cbSJens Wiklander const unsigned char *hash, 2658817466cbSJens Wiklander const unsigned char *sig) 2659817466cbSJens Wiklander { 26603d3b0591SJens Wiklander mbedtls_md_type_t mgf1_hash_id; 266132b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 266232b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 266332b31808SJens Wiklander } 26643d3b0591SJens Wiklander 26653d3b0591SJens Wiklander mgf1_hash_id = (ctx->hash_id != MBEDTLS_MD_NONE) 2666817466cbSJens Wiklander ? (mbedtls_md_type_t) ctx->hash_id 2667817466cbSJens Wiklander : md_alg; 2668817466cbSJens Wiklander 266932b31808SJens Wiklander return mbedtls_rsa_rsassa_pss_verify_ext(ctx, 2670817466cbSJens Wiklander md_alg, hashlen, hash, 267132b31808SJens Wiklander mgf1_hash_id, 267232b31808SJens Wiklander MBEDTLS_RSA_SALT_LEN_ANY, 267332b31808SJens Wiklander sig); 2674817466cbSJens Wiklander 2675817466cbSJens Wiklander } 2676817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V21 */ 2677817466cbSJens Wiklander 2678817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2679817466cbSJens Wiklander /* 2680817466cbSJens Wiklander * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function 2681817466cbSJens Wiklander */ 2682817466cbSJens Wiklander int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx, 2683817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2684817466cbSJens Wiklander unsigned int hashlen, 2685817466cbSJens Wiklander const unsigned char *hash, 2686817466cbSJens Wiklander const unsigned char *sig) 2687817466cbSJens Wiklander { 26883d3b0591SJens Wiklander int ret = 0; 26893d3b0591SJens Wiklander size_t sig_len; 26903d3b0591SJens Wiklander unsigned char *encoded = NULL, *encoded_expected = NULL; 26913d3b0591SJens Wiklander 269232b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 269332b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 269432b31808SJens Wiklander } 26953d3b0591SJens Wiklander 26963d3b0591SJens Wiklander sig_len = ctx->len; 2697817466cbSJens Wiklander 26983d3b0591SJens Wiklander /* 26993d3b0591SJens Wiklander * Prepare expected PKCS1 v1.5 encoding of hash. 27003d3b0591SJens Wiklander */ 2701817466cbSJens Wiklander 27023d3b0591SJens Wiklander if ((encoded = mbedtls_calloc(1, sig_len)) == NULL || 270332b31808SJens Wiklander (encoded_expected = mbedtls_calloc(1, sig_len)) == NULL) { 27043d3b0591SJens Wiklander ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; 27053d3b0591SJens Wiklander goto cleanup; 27063d3b0591SJens Wiklander } 27073d3b0591SJens Wiklander 27083d3b0591SJens Wiklander if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len, 270932b31808SJens Wiklander encoded_expected)) != 0) { 27103d3b0591SJens Wiklander goto cleanup; 271132b31808SJens Wiklander } 27123d3b0591SJens Wiklander 27133d3b0591SJens Wiklander /* 27143d3b0591SJens Wiklander * Apply RSA primitive to get what should be PKCS1 encoded hash. 27153d3b0591SJens Wiklander */ 2716817466cbSJens Wiklander 271732b31808SJens Wiklander ret = mbedtls_rsa_public(ctx, sig, encoded); 271832b31808SJens Wiklander if (ret != 0) { 27193d3b0591SJens Wiklander goto cleanup; 272032b31808SJens Wiklander } 27213d3b0591SJens Wiklander 27223d3b0591SJens Wiklander /* 27233d3b0591SJens Wiklander * Compare 27243d3b0591SJens Wiklander */ 27253d3b0591SJens Wiklander 272606de6080SJens Wiklander if ((ret = FTMN_CALLEE_DONE_MEMCMP(mbedtls_ct_memcmp, encoded, 272732b31808SJens Wiklander encoded_expected, sig_len )) != 0) { 27283d3b0591SJens Wiklander ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; 27293d3b0591SJens Wiklander goto cleanup; 27303d3b0591SJens Wiklander } 27313d3b0591SJens Wiklander 27323d3b0591SJens Wiklander cleanup: 27333d3b0591SJens Wiklander 273432b31808SJens Wiklander if (encoded != NULL) { 2735*b0563631STom Van Eyck mbedtls_zeroize_and_free(encoded, sig_len); 27363d3b0591SJens Wiklander } 27373d3b0591SJens Wiklander 273832b31808SJens Wiklander if (encoded_expected != NULL) { 2739*b0563631STom Van Eyck mbedtls_zeroize_and_free(encoded_expected, sig_len); 27403d3b0591SJens Wiklander } 27413d3b0591SJens Wiklander 274232b31808SJens Wiklander return ret; 2743817466cbSJens Wiklander } 2744817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 2745817466cbSJens Wiklander 2746817466cbSJens Wiklander /* 2747817466cbSJens Wiklander * Do an RSA operation and check the message digest 2748817466cbSJens Wiklander */ 2749817466cbSJens Wiklander int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx, 2750817466cbSJens Wiklander mbedtls_md_type_t md_alg, 2751817466cbSJens Wiklander unsigned int hashlen, 2752817466cbSJens Wiklander const unsigned char *hash, 2753817466cbSJens Wiklander const unsigned char *sig) 2754817466cbSJens Wiklander { 275532b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { 275632b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 275732b31808SJens Wiklander } 27583d3b0591SJens Wiklander 275932b31808SJens Wiklander switch (ctx->padding) { 2760817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2761817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V15: 276232b31808SJens Wiklander return mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx, md_alg, 2763817466cbSJens Wiklander hashlen, hash, sig); 2764817466cbSJens Wiklander #endif 2765817466cbSJens Wiklander 2766817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V21) 2767817466cbSJens Wiklander case MBEDTLS_RSA_PKCS_V21: 276832b31808SJens Wiklander return mbedtls_rsa_rsassa_pss_verify(ctx, md_alg, 2769817466cbSJens Wiklander hashlen, hash, sig); 2770817466cbSJens Wiklander #endif 2771817466cbSJens Wiklander 2772817466cbSJens Wiklander default: 277332b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 2774817466cbSJens Wiklander } 2775817466cbSJens Wiklander } 2776817466cbSJens Wiklander 2777817466cbSJens Wiklander /* 2778817466cbSJens Wiklander * Copy the components of an RSA key 2779817466cbSJens Wiklander */ 2780817466cbSJens Wiklander int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src) 2781817466cbSJens Wiklander { 278211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2783817466cbSJens Wiklander 2784817466cbSJens Wiklander dst->len = src->len; 2785817466cbSJens Wiklander 2786817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->N, &src->N)); 2787817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->E, &src->E)); 2788817466cbSJens Wiklander 2789817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->D, &src->D)); 2790817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->P, &src->P)); 2791817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Q, &src->Q)); 27923d3b0591SJens Wiklander 27933d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 2794817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DP, &src->DP)); 2795817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DQ, &src->DQ)); 2796817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->QP, &src->QP)); 2797817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RP, &src->RP)); 2798817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RQ, &src->RQ)); 27993d3b0591SJens Wiklander #endif 28003d3b0591SJens Wiklander 28013d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RN, &src->RN)); 2802817466cbSJens Wiklander 2803817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vi, &src->Vi)); 2804817466cbSJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vf, &src->Vf)); 2805817466cbSJens Wiklander 2806817466cbSJens Wiklander dst->padding = src->padding; 2807817466cbSJens Wiklander dst->hash_id = src->hash_id; 2808817466cbSJens Wiklander 2809817466cbSJens Wiklander cleanup: 281032b31808SJens Wiklander if (ret != 0) { 2811817466cbSJens Wiklander mbedtls_rsa_free(dst); 281232b31808SJens Wiklander } 2813817466cbSJens Wiklander 281432b31808SJens Wiklander return ret; 2815817466cbSJens Wiklander } 2816817466cbSJens Wiklander 2817817466cbSJens Wiklander /* 2818817466cbSJens Wiklander * Free the components of an RSA key 2819817466cbSJens Wiklander */ 2820817466cbSJens Wiklander void mbedtls_rsa_free(mbedtls_rsa_context *ctx) 2821817466cbSJens Wiklander { 282232b31808SJens Wiklander if (ctx == NULL) { 28233d3b0591SJens Wiklander return; 282432b31808SJens Wiklander } 28253d3b0591SJens Wiklander 28263d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->Vi); 28273d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->Vf); 28283d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->RN); 28293d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->D); 28303d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->Q); 28313d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->P); 28323d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->E); 28333d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->N); 28343d3b0591SJens Wiklander 28353d3b0591SJens Wiklander #if !defined(MBEDTLS_RSA_NO_CRT) 28363d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->RQ); 28373d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->RP); 28383d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->QP); 28393d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->DQ); 28403d3b0591SJens Wiklander mbedtls_mpi_free(&ctx->DP); 28413d3b0591SJens Wiklander #endif /* MBEDTLS_RSA_NO_CRT */ 2842817466cbSJens Wiklander 2843817466cbSJens Wiklander #if defined(MBEDTLS_THREADING_C) 28447901324dSJerome Forissier /* Free the mutex, but only if it hasn't been freed already. */ 284532b31808SJens Wiklander if (ctx->ver != 0) { 2846817466cbSJens Wiklander mbedtls_mutex_free(&ctx->mutex); 28477901324dSJerome Forissier ctx->ver = 0; 28487901324dSJerome Forissier } 2849817466cbSJens Wiklander #endif 2850817466cbSJens Wiklander } 2851817466cbSJens Wiklander 28523d3b0591SJens Wiklander #endif /* !MBEDTLS_RSA_ALT */ 28533d3b0591SJens Wiklander 2854817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 2855817466cbSJens Wiklander 2856817466cbSJens Wiklander 2857817466cbSJens Wiklander /* 2858817466cbSJens Wiklander * Example RSA-1024 keypair, for test purposes 2859817466cbSJens Wiklander */ 2860817466cbSJens Wiklander #define KEY_LEN 128 2861817466cbSJens Wiklander 2862817466cbSJens Wiklander #define RSA_N "9292758453063D803DD603D5E777D788" \ 2863817466cbSJens Wiklander "8ED1D5BF35786190FA2F23EBC0848AEA" \ 2864817466cbSJens Wiklander "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ 2865817466cbSJens Wiklander "7130B9CED7ACDF54CFC7555AC14EEBAB" \ 2866817466cbSJens Wiklander "93A89813FBF3C4F8066D2D800F7C38A8" \ 2867817466cbSJens Wiklander "1AE31942917403FF4946B0A83D3D3E05" \ 2868817466cbSJens Wiklander "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ 2869817466cbSJens Wiklander "5E94BB77B07507233A0BC7BAC8F90F79" 2870817466cbSJens Wiklander 2871817466cbSJens Wiklander #define RSA_E "10001" 2872817466cbSJens Wiklander 2873817466cbSJens Wiklander #define RSA_D "24BF6185468786FDD303083D25E64EFC" \ 2874817466cbSJens Wiklander "66CA472BC44D253102F8B4A9D3BFA750" \ 2875817466cbSJens Wiklander "91386C0077937FE33FA3252D28855837" \ 2876817466cbSJens Wiklander "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ 2877817466cbSJens Wiklander "DF79C5CE07EE72C7F123142198164234" \ 2878817466cbSJens Wiklander "CABB724CF78B8173B9F880FC86322407" \ 2879817466cbSJens Wiklander "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ 2880817466cbSJens Wiklander "071513A1E85B5DFA031F21ECAE91A34D" 2881817466cbSJens Wiklander 2882817466cbSJens Wiklander #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ 2883817466cbSJens Wiklander "2C01CAD19EA484A87EA4377637E75500" \ 2884817466cbSJens Wiklander "FCB2005C5C7DD6EC4AC023CDA285D796" \ 2885817466cbSJens Wiklander "C3D9E75E1EFC42488BB4F1D13AC30A57" 2886817466cbSJens Wiklander 2887817466cbSJens Wiklander #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ 2888817466cbSJens Wiklander "E211C2B9E5DB1ED0BF61D0D9899620F4" \ 2889817466cbSJens Wiklander "910E4168387E3C30AA1E00C339A79508" \ 2890817466cbSJens Wiklander "8452DD96A9A5EA5D9DCA68DA636032AF" 2891817466cbSJens Wiklander 2892817466cbSJens Wiklander #define PT_LEN 24 2893817466cbSJens Wiklander #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ 2894817466cbSJens Wiklander "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" 2895817466cbSJens Wiklander 2896817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2897817466cbSJens Wiklander static int myrand(void *rng_state, unsigned char *output, size_t len) 2898817466cbSJens Wiklander { 28997901324dSJerome Forissier #if !defined(__OpenBSD__) && !defined(__NetBSD__) 2900817466cbSJens Wiklander size_t i; 2901817466cbSJens Wiklander 290232b31808SJens Wiklander if (rng_state != NULL) { 2903817466cbSJens Wiklander rng_state = NULL; 290432b31808SJens Wiklander } 2905817466cbSJens Wiklander 290632b31808SJens Wiklander for (i = 0; i < len; ++i) { 2907817466cbSJens Wiklander output[i] = rand(); 290832b31808SJens Wiklander } 2909817466cbSJens Wiklander #else 291032b31808SJens Wiklander if (rng_state != NULL) { 2911817466cbSJens Wiklander rng_state = NULL; 291232b31808SJens Wiklander } 2913817466cbSJens Wiklander 2914817466cbSJens Wiklander arc4random_buf(output, len); 29157901324dSJerome Forissier #endif /* !OpenBSD && !NetBSD */ 2916817466cbSJens Wiklander 291732b31808SJens Wiklander return 0; 2918817466cbSJens Wiklander } 2919817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 2920817466cbSJens Wiklander 2921817466cbSJens Wiklander /* 2922817466cbSJens Wiklander * Checkup routine 2923817466cbSJens Wiklander */ 2924817466cbSJens Wiklander int mbedtls_rsa_self_test(int verbose) 2925817466cbSJens Wiklander { 2926817466cbSJens Wiklander int ret = 0; 2927817466cbSJens Wiklander #if defined(MBEDTLS_PKCS1_V15) 2928817466cbSJens Wiklander size_t len; 2929817466cbSJens Wiklander mbedtls_rsa_context rsa; 2930817466cbSJens Wiklander unsigned char rsa_plaintext[PT_LEN]; 2931817466cbSJens Wiklander unsigned char rsa_decrypted[PT_LEN]; 2932817466cbSJens Wiklander unsigned char rsa_ciphertext[KEY_LEN]; 2933*b0563631STom Van Eyck #if defined(MBEDTLS_MD_CAN_SHA1) 2934817466cbSJens Wiklander unsigned char sha1sum[20]; 2935817466cbSJens Wiklander #endif 2936817466cbSJens Wiklander 29373d3b0591SJens Wiklander mbedtls_mpi K; 29383d3b0591SJens Wiklander 29393d3b0591SJens Wiklander mbedtls_mpi_init(&K); 294032b31808SJens Wiklander mbedtls_rsa_init(&rsa); 2941817466cbSJens Wiklander 29423d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_N)); 29433d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, &K, NULL, NULL, NULL, NULL)); 29443d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_P)); 29453d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, &K, NULL, NULL, NULL)); 29463d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_Q)); 29473d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, &K, NULL, NULL)); 29483d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_D)); 29493d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, &K, NULL)); 29503d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_E)); 29513d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, NULL, &K)); 29523d3b0591SJens Wiklander 29533d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_rsa_complete(&rsa)); 2954817466cbSJens Wiklander 295532b31808SJens Wiklander if (verbose != 0) { 2956817466cbSJens Wiklander mbedtls_printf(" RSA key validation: "); 295732b31808SJens Wiklander } 2958817466cbSJens Wiklander 2959817466cbSJens Wiklander if (mbedtls_rsa_check_pubkey(&rsa) != 0 || 296032b31808SJens Wiklander mbedtls_rsa_check_privkey(&rsa) != 0) { 296132b31808SJens Wiklander if (verbose != 0) { 2962817466cbSJens Wiklander mbedtls_printf("failed\n"); 296332b31808SJens Wiklander } 2964817466cbSJens Wiklander 29653d3b0591SJens Wiklander ret = 1; 29663d3b0591SJens Wiklander goto cleanup; 2967817466cbSJens Wiklander } 2968817466cbSJens Wiklander 296932b31808SJens Wiklander if (verbose != 0) { 2970817466cbSJens Wiklander mbedtls_printf("passed\n PKCS#1 encryption : "); 297132b31808SJens Wiklander } 2972817466cbSJens Wiklander 2973817466cbSJens Wiklander memcpy(rsa_plaintext, RSA_PT, PT_LEN); 2974817466cbSJens Wiklander 297532b31808SJens Wiklander if (mbedtls_rsa_pkcs1_encrypt(&rsa, myrand, NULL, 29763d3b0591SJens Wiklander PT_LEN, rsa_plaintext, 297732b31808SJens Wiklander rsa_ciphertext) != 0) { 297832b31808SJens Wiklander if (verbose != 0) { 2979817466cbSJens Wiklander mbedtls_printf("failed\n"); 298032b31808SJens Wiklander } 2981817466cbSJens Wiklander 29823d3b0591SJens Wiklander ret = 1; 29833d3b0591SJens Wiklander goto cleanup; 2984817466cbSJens Wiklander } 2985817466cbSJens Wiklander 298632b31808SJens Wiklander if (verbose != 0) { 2987817466cbSJens Wiklander mbedtls_printf("passed\n PKCS#1 decryption : "); 298832b31808SJens Wiklander } 2989817466cbSJens Wiklander 299032b31808SJens Wiklander if (mbedtls_rsa_pkcs1_decrypt(&rsa, myrand, NULL, 29913d3b0591SJens Wiklander &len, rsa_ciphertext, rsa_decrypted, 299232b31808SJens Wiklander sizeof(rsa_decrypted)) != 0) { 299332b31808SJens Wiklander if (verbose != 0) { 2994817466cbSJens Wiklander mbedtls_printf("failed\n"); 299532b31808SJens Wiklander } 2996817466cbSJens Wiklander 29973d3b0591SJens Wiklander ret = 1; 29983d3b0591SJens Wiklander goto cleanup; 2999817466cbSJens Wiklander } 3000817466cbSJens Wiklander 300132b31808SJens Wiklander if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) { 300232b31808SJens Wiklander if (verbose != 0) { 3003817466cbSJens Wiklander mbedtls_printf("failed\n"); 300432b31808SJens Wiklander } 3005817466cbSJens Wiklander 30063d3b0591SJens Wiklander ret = 1; 30073d3b0591SJens Wiklander goto cleanup; 3008817466cbSJens Wiklander } 3009817466cbSJens Wiklander 301032b31808SJens Wiklander if (verbose != 0) { 3011817466cbSJens Wiklander mbedtls_printf("passed\n"); 301232b31808SJens Wiklander } 3013817466cbSJens Wiklander 3014*b0563631STom Van Eyck #if defined(MBEDTLS_MD_CAN_SHA1) 301532b31808SJens Wiklander if (verbose != 0) { 3016817466cbSJens Wiklander mbedtls_printf(" PKCS#1 data sign : "); 301732b31808SJens Wiklander } 3018817466cbSJens Wiklander 301932b31808SJens Wiklander if (mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 302032b31808SJens Wiklander rsa_plaintext, PT_LEN, sha1sum) != 0) { 302132b31808SJens Wiklander if (verbose != 0) { 3022817466cbSJens Wiklander mbedtls_printf("failed\n"); 302332b31808SJens Wiklander } 3024817466cbSJens Wiklander 302532b31808SJens Wiklander return 1; 3026817466cbSJens Wiklander } 3027817466cbSJens Wiklander 30283d3b0591SJens Wiklander if (mbedtls_rsa_pkcs1_sign(&rsa, myrand, NULL, 302932b31808SJens Wiklander MBEDTLS_MD_SHA1, 20, 303032b31808SJens Wiklander sha1sum, rsa_ciphertext) != 0) { 303132b31808SJens Wiklander if (verbose != 0) { 3032817466cbSJens Wiklander mbedtls_printf("failed\n"); 303332b31808SJens Wiklander } 3034817466cbSJens Wiklander 30353d3b0591SJens Wiklander ret = 1; 30363d3b0591SJens Wiklander goto cleanup; 30373d3b0591SJens Wiklander } 30383d3b0591SJens Wiklander 303932b31808SJens Wiklander if (verbose != 0) { 30403d3b0591SJens Wiklander mbedtls_printf("passed\n PKCS#1 sig. verify: "); 304132b31808SJens Wiklander } 30423d3b0591SJens Wiklander 304332b31808SJens Wiklander if (mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA1, 20, 304432b31808SJens Wiklander sha1sum, rsa_ciphertext) != 0) { 304532b31808SJens Wiklander if (verbose != 0) { 30463d3b0591SJens Wiklander mbedtls_printf("failed\n"); 304732b31808SJens Wiklander } 30483d3b0591SJens Wiklander 30493d3b0591SJens Wiklander ret = 1; 30503d3b0591SJens Wiklander goto cleanup; 3051817466cbSJens Wiklander } 3052817466cbSJens Wiklander 305332b31808SJens Wiklander if (verbose != 0) { 3054817466cbSJens Wiklander mbedtls_printf("passed\n"); 305532b31808SJens Wiklander } 3056*b0563631STom Van Eyck #endif /* MBEDTLS_MD_CAN_SHA1 */ 3057817466cbSJens Wiklander 305832b31808SJens Wiklander if (verbose != 0) { 3059817466cbSJens Wiklander mbedtls_printf("\n"); 306032b31808SJens Wiklander } 3061817466cbSJens Wiklander 3062817466cbSJens Wiklander cleanup: 30633d3b0591SJens Wiklander mbedtls_mpi_free(&K); 3064817466cbSJens Wiklander mbedtls_rsa_free(&rsa); 3065817466cbSJens Wiklander #else /* MBEDTLS_PKCS1_V15 */ 3066817466cbSJens Wiklander ((void) verbose); 3067817466cbSJens Wiklander #endif /* MBEDTLS_PKCS1_V15 */ 306832b31808SJens Wiklander return ret; 3069817466cbSJens Wiklander } 3070817466cbSJens Wiklander 3071817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 3072817466cbSJens Wiklander 3073817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 3074