xref: /freebsd-src/crypto/libecc/src/examples/sig/rsa/rsa_tests.h (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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