1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2021 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * 8*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 9*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 10*f0865ec9SKyle Evans */ 11*f0865ec9SKyle Evans #ifndef __RSA_TESTS_H__ 12*f0865ec9SKyle Evans #define __RSA_TESTS_H__ 13*f0865ec9SKyle Evans 14*f0865ec9SKyle Evans /* Test suite for RSA PKCS#1 algorithms */ 15*f0865ec9SKyle Evans #include "rsa.h" 16*f0865ec9SKyle Evans 17*f0865ec9SKyle Evans typedef enum { 18*f0865ec9SKyle Evans RSA_PKCS1_v1_5_ENC = 0, 19*f0865ec9SKyle Evans RSA_PKCS1_v1_5_SIG = 1, 20*f0865ec9SKyle Evans RSA_OAEP_ENC = 2, 21*f0865ec9SKyle Evans RSA_PSS_SIG = 3, 22*f0865ec9SKyle Evans } rsa_alg_type; 23*f0865ec9SKyle Evans 24*f0865ec9SKyle Evans typedef struct { 25*f0865ec9SKyle Evans const char *name; 26*f0865ec9SKyle Evans rsa_alg_type type; 27*f0865ec9SKyle Evans u32 modbits; 28*f0865ec9SKyle Evans gen_hash_alg_type hash; 29*f0865ec9SKyle Evans const u8 *n; 30*f0865ec9SKyle Evans u16 nlen; 31*f0865ec9SKyle Evans const u8 *d; 32*f0865ec9SKyle Evans u16 dlen; 33*f0865ec9SKyle Evans const u8 *e; 34*f0865ec9SKyle Evans u16 elen; 35*f0865ec9SKyle Evans const u8 *p; 36*f0865ec9SKyle Evans u16 plen; 37*f0865ec9SKyle Evans const u8 *q; 38*f0865ec9SKyle Evans u16 qlen; 39*f0865ec9SKyle Evans const u8 *dP; 40*f0865ec9SKyle Evans u16 dPlen; 41*f0865ec9SKyle Evans const u8 *dQ; 42*f0865ec9SKyle Evans u16 dQlen; 43*f0865ec9SKyle Evans const u8 *qInv; 44*f0865ec9SKyle Evans u16 qInvlen; 45*f0865ec9SKyle Evans const u8 *m; 46*f0865ec9SKyle Evans u32 mlen; 47*f0865ec9SKyle Evans const u8 *res; 48*f0865ec9SKyle Evans u32 reslen; 49*f0865ec9SKyle Evans const u8 *salt; 50*f0865ec9SKyle Evans u32 saltlen; 51*f0865ec9SKyle Evans } rsa_test; 52*f0865ec9SKyle Evans 53*f0865ec9SKyle Evans 54*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static inline int perform_rsa_tests(const rsa_test **tests, u32 num_tests) 55*f0865ec9SKyle Evans { 56*f0865ec9SKyle Evans int ret = 0, cmp; 57*f0865ec9SKyle Evans unsigned int i; 58*f0865ec9SKyle Evans 59*f0865ec9SKyle Evans for(i = 0; i < num_tests; i++){ 60*f0865ec9SKyle Evans const rsa_test *t = tests[i]; 61*f0865ec9SKyle Evans u32 modbits = t->modbits; 62*f0865ec9SKyle Evans rsa_pub_key pub; 63*f0865ec9SKyle Evans rsa_priv_key priv; 64*f0865ec9SKyle Evans rsa_priv_key priv_pq; 65*f0865ec9SKyle Evans 66*f0865ec9SKyle Evans /* Import the keys */ 67*f0865ec9SKyle Evans ret = rsa_import_pub_key(&pub, t->n, (u16)t->nlen, t->e, (u16)t->elen); EG(ret, err1); 68*f0865ec9SKyle Evans if(t->dP == NULL){ 69*f0865ec9SKyle Evans const rsa_test *t_ = NULL; 70*f0865ec9SKyle Evans MUST_HAVE((num_tests > 1) && (i < (num_tests - 1)), ret, err); 71*f0865ec9SKyle Evans /* NOTE: we use the "next" CRT test to extract p and q */ 72*f0865ec9SKyle Evans t_ = tests[i + 1]; 73*f0865ec9SKyle Evans MUST_HAVE((t_->dP != NULL), ret, err); 74*f0865ec9SKyle Evans /* Import the RSA_SIMPLE private key with only d and n */ 75*f0865ec9SKyle Evans ret = rsa_import_simple_priv_key(&priv, t->n, (u16)t->nlen, t->d, (u16)t->dlen, NULL, 0, NULL, 0); EG(ret, err1); 76*f0865ec9SKyle Evans /* Import the RSA_SIMPLE_PQ with d, n, p and q */ 77*f0865ec9SKyle Evans ret = rsa_import_simple_priv_key(&priv_pq, t->n, (u16)t->nlen, t->d, (u16)t->dlen, t_->p, (u16)t_->plen, t_->q, (u16)t_->qlen); EG(ret, err1); 78*f0865ec9SKyle Evans } 79*f0865ec9SKyle Evans else{ 80*f0865ec9SKyle Evans /* Import the RSA_CRT CRT key */ 81*f0865ec9SKyle Evans ret = rsa_import_crt_priv_key(&priv, t->p, (u16)t->plen, t->q, (u16)t->qlen, t->dP, (u16)t->dPlen, t->dQ, (u16)t->dQlen, t->qInv, (u16)t->qInvlen, NULL, NULL, 0); EG(ret, err1); 82*f0865ec9SKyle Evans } 83*f0865ec9SKyle Evans #ifdef USE_SIG_BLINDING 84*f0865ec9SKyle Evans /* We using exponent blinding, only RSA_SIMPLE_PQ are usable. We hence overwrite the key */ 85*f0865ec9SKyle Evans ret = local_memcpy(&priv, &priv_pq, sizeof(rsa_priv_key)); EG(ret, err); 86*f0865ec9SKyle Evans #endif 87*f0865ec9SKyle Evans /* Perform our operation */ 88*f0865ec9SKyle Evans switch(t->type){ 89*f0865ec9SKyle Evans case RSA_PKCS1_v1_5_ENC:{ 90*f0865ec9SKyle Evans u8 cipher[NN_USABLE_MAX_BYTE_LEN]; 91*f0865ec9SKyle Evans u32 clen; 92*f0865ec9SKyle Evans if(t->salt != NULL){ 93*f0865ec9SKyle Evans clen = sizeof(cipher); 94*f0865ec9SKyle Evans ret = rsaes_pkcs1_v1_5_encrypt(&pub, t->m, t->mlen, cipher, &clen, modbits, t->salt, t->saltlen); EG(ret, err1); 95*f0865ec9SKyle Evans /* Check the result */ 96*f0865ec9SKyle Evans MUST_HAVE((clen == t->reslen), ret, err1); 97*f0865ec9SKyle Evans ret = are_equal(t->res, cipher, t->reslen, &cmp); EG(ret, err1); 98*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 99*f0865ec9SKyle Evans } 100*f0865ec9SKyle Evans /* Try to decrypt */ 101*f0865ec9SKyle Evans clen = sizeof(cipher); 102*f0865ec9SKyle Evans ret = rsaes_pkcs1_v1_5_decrypt(&priv, t->res, t->reslen, cipher, &clen, modbits); EG(ret, err1); 103*f0865ec9SKyle Evans /* Check the result */ 104*f0865ec9SKyle Evans MUST_HAVE((clen == t->mlen), ret, err1); 105*f0865ec9SKyle Evans ret = are_equal(t->m, cipher, t->mlen, &cmp); EG(ret, err1); 106*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 107*f0865ec9SKyle Evans /* Try to decrypt with the hardened version */ 108*f0865ec9SKyle Evans clen = sizeof(cipher); 109*f0865ec9SKyle Evans ret = rsaes_pkcs1_v1_5_decrypt_hardened(&priv, &pub, t->res, t->reslen, cipher, &clen, modbits); EG(ret, err1); 110*f0865ec9SKyle Evans /* Check the result */ 111*f0865ec9SKyle Evans MUST_HAVE((clen == t->mlen), ret, err1); 112*f0865ec9SKyle Evans ret = are_equal(t->m, cipher, t->mlen, &cmp); EG(ret, err1); 113*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 114*f0865ec9SKyle Evans break; 115*f0865ec9SKyle Evans } 116*f0865ec9SKyle Evans case RSA_OAEP_ENC:{ 117*f0865ec9SKyle Evans u8 cipher[NN_USABLE_MAX_BYTE_LEN]; 118*f0865ec9SKyle Evans u32 clen; 119*f0865ec9SKyle Evans if(t->salt != NULL){ 120*f0865ec9SKyle Evans clen = sizeof(cipher); 121*f0865ec9SKyle Evans ret = rsaes_oaep_encrypt(&pub, t->m, t->mlen, cipher, &clen, modbits, NULL, 0, t->hash, t->hash, t->salt, t->saltlen); EG(ret, err1); 122*f0865ec9SKyle Evans /* Check the result */ 123*f0865ec9SKyle Evans MUST_HAVE((clen == t->reslen), ret, err1); 124*f0865ec9SKyle Evans ret = are_equal(t->res, cipher, t->reslen, &cmp); EG(ret, err1); 125*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 126*f0865ec9SKyle Evans } 127*f0865ec9SKyle Evans /* Try to decrypt */ 128*f0865ec9SKyle Evans clen = sizeof(cipher); 129*f0865ec9SKyle Evans ret = rsaes_oaep_decrypt(&priv, t->res, t->reslen, cipher, &clen, modbits, NULL, 0, t->hash, t->hash); EG(ret, err1); 130*f0865ec9SKyle Evans /* Check the result */ 131*f0865ec9SKyle Evans MUST_HAVE((clen == t->mlen), ret, err1); 132*f0865ec9SKyle Evans ret = are_equal(t->m, cipher, t->mlen, &cmp); EG(ret, err1); 133*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 134*f0865ec9SKyle Evans /* Try to decrypt with the hardened version */ 135*f0865ec9SKyle Evans clen = sizeof(cipher); 136*f0865ec9SKyle Evans ret = rsaes_oaep_decrypt_hardened(&priv, &pub, t->res, t->reslen, cipher, &clen, modbits, NULL, 0, t->hash, t->hash); EG(ret, err1); 137*f0865ec9SKyle Evans /* Check the result */ 138*f0865ec9SKyle Evans MUST_HAVE((clen == t->mlen), ret, err1); 139*f0865ec9SKyle Evans ret = are_equal(t->m, cipher, t->mlen, &cmp); EG(ret, err1); 140*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 141*f0865ec9SKyle Evans break; 142*f0865ec9SKyle Evans } 143*f0865ec9SKyle Evans case RSA_PKCS1_v1_5_SIG:{ 144*f0865ec9SKyle Evans u8 sig[NN_USABLE_MAX_BYTE_LEN]; 145*f0865ec9SKyle Evans u16 siglen = sizeof(sig); 146*f0865ec9SKyle Evans MUST_HAVE((t->reslen) <= 0xffff, ret, err1); 147*f0865ec9SKyle Evans ret = rsassa_pkcs1_v1_5_verify(&pub, t->m, t->mlen, t->res, (u16)(t->reslen), modbits, t->hash); EG(ret, err1); 148*f0865ec9SKyle Evans /* Try to sign */ 149*f0865ec9SKyle Evans ret = rsassa_pkcs1_v1_5_sign(&priv, t->m, t->mlen, sig, &siglen, modbits, t->hash); EG(ret, err1); 150*f0865ec9SKyle Evans /* Check the result */ 151*f0865ec9SKyle Evans MUST_HAVE((siglen == t->reslen), ret, err1); 152*f0865ec9SKyle Evans ret = are_equal(t->res, sig, t->reslen, &cmp); EG(ret, err1); 153*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 154*f0865ec9SKyle Evans /* Try to sign with the hardened version */ 155*f0865ec9SKyle Evans ret = rsassa_pkcs1_v1_5_sign_hardened(&priv, &pub, t->m, t->mlen, sig, &siglen, modbits, t->hash); EG(ret, err1); 156*f0865ec9SKyle Evans /* Check the result */ 157*f0865ec9SKyle Evans MUST_HAVE((siglen == t->reslen), ret, err1); 158*f0865ec9SKyle Evans ret = are_equal(t->res, sig, t->reslen, &cmp); EG(ret, err1); 159*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 160*f0865ec9SKyle Evans break; 161*f0865ec9SKyle Evans } 162*f0865ec9SKyle Evans case RSA_PSS_SIG:{ 163*f0865ec9SKyle Evans if(t->salt == NULL){ 164*f0865ec9SKyle Evans /* In case of NULL salt, default saltlen value is the digest size */ 165*f0865ec9SKyle Evans u8 digestsize, blocksize; 166*f0865ec9SKyle Evans ret = gen_hash_get_hash_sizes(t->hash, &digestsize, &blocksize); EG(ret, err1); 167*f0865ec9SKyle Evans MUST_HAVE((t->reslen) <= 0xffff, ret, err1); 168*f0865ec9SKyle Evans ret = rsassa_pss_verify(&pub, t->m, t->mlen, t->res, (u16)(t->reslen), modbits, t->hash, t->hash, digestsize); EG(ret, err1); 169*f0865ec9SKyle Evans } 170*f0865ec9SKyle Evans else{ 171*f0865ec9SKyle Evans MUST_HAVE((t->reslen) <= 0xffff, ret, err1); 172*f0865ec9SKyle Evans ret = rsassa_pss_verify(&pub, t->m, t->mlen, t->res, (u16)(t->reslen), modbits, t->hash, t->hash, t->saltlen); EG(ret, err1); 173*f0865ec9SKyle Evans } 174*f0865ec9SKyle Evans if(t->salt != NULL){ 175*f0865ec9SKyle Evans /* Try to sign */ 176*f0865ec9SKyle Evans u8 sig[NN_USABLE_MAX_BYTE_LEN]; 177*f0865ec9SKyle Evans u16 siglen = sizeof(sig); 178*f0865ec9SKyle Evans ret = rsassa_pss_sign(&priv, t->m, t->mlen, sig, &siglen, modbits, t->hash, t->hash, t->saltlen, t->salt); EG(ret, err1); 179*f0865ec9SKyle Evans /* Check the result */ 180*f0865ec9SKyle Evans MUST_HAVE((t->reslen) <= 0xffff, ret, err1); 181*f0865ec9SKyle Evans MUST_HAVE((siglen == (u16)(t->reslen)), ret, err1); 182*f0865ec9SKyle Evans ret = are_equal(t->res, sig, t->reslen, &cmp); EG(ret, err1); 183*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 184*f0865ec9SKyle Evans /* Try to sign with the hardened version */ 185*f0865ec9SKyle Evans ret = rsassa_pss_sign_hardened(&priv, &pub, t->m, t->mlen, sig, &siglen, modbits, t->hash, t->hash, t->saltlen, t->salt); EG(ret, err1); 186*f0865ec9SKyle Evans /* Check the result */ 187*f0865ec9SKyle Evans MUST_HAVE((siglen == (u16)(t->reslen)), ret, err1); 188*f0865ec9SKyle Evans ret = are_equal(t->res, sig, t->reslen, &cmp); EG(ret, err1); 189*f0865ec9SKyle Evans MUST_HAVE(cmp, ret, err1); 190*f0865ec9SKyle Evans } 191*f0865ec9SKyle Evans break; 192*f0865ec9SKyle Evans } 193*f0865ec9SKyle Evans default:{ 194*f0865ec9SKyle Evans ret = -1; 195*f0865ec9SKyle Evans break; 196*f0865ec9SKyle Evans } 197*f0865ec9SKyle Evans } 198*f0865ec9SKyle Evans err1: 199*f0865ec9SKyle Evans if(ret){ 200*f0865ec9SKyle Evans ext_printf("[-] Test %s failed (modbits = %" PRIu32 ")\n", t->name, t->modbits); 201*f0865ec9SKyle Evans goto err; 202*f0865ec9SKyle Evans } 203*f0865ec9SKyle Evans else{ 204*f0865ec9SKyle Evans ext_printf("[+] Test %s passed (modbits = %" PRIu32 ")\n", t->name, t->modbits); 205*f0865ec9SKyle Evans } 206*f0865ec9SKyle Evans } 207*f0865ec9SKyle Evans 208*f0865ec9SKyle Evans if(!ret){ 209*f0865ec9SKyle Evans ext_printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\t=== [+] All RSA tests went OK! ===\n"); 210*f0865ec9SKyle Evans } 211*f0865ec9SKyle Evans err: 212*f0865ec9SKyle Evans return ret; 213*f0865ec9SKyle Evans } 214*f0865ec9SKyle Evans 215*f0865ec9SKyle Evans #endif /* __RSA_TESTS_H__ */ 216