/* Copyright (c) (2011,2014,2015,2016,2018,2019) Apple Inc. All rights reserved. * * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which * is contained in the License.txt file distributed with corecrypto) and only to * people who accept that license. IMPORTANT: Any license rights granted to you by * Apple Inc. (if any) are limited to internal use within your organization only on * devices and computers you own or control, for the sole purpose of verifying the * security characteristics and correct functioning of the Apple Software. You may * not, directly or indirectly, redistribute the Apple Software or any portions thereof. */ #include #include "cctest.h" #include "testmore.h" #include "crypto_test_dh.h" int ccdh_test_compute_vector(const struct ccdh_compute_vector *v) { int result,r1,r2; const cc_size n = ccn_nof(v->len); const size_t s = ccn_sizeof_n(n); unsigned char z[v->zLen]; size_t zLen; unsigned char tmp[v->zLen]; // for negative testing uint32_t status=0; uint32_t nb_test=0; ccdh_gp_decl(s, gp); ccdh_full_ctx_decl(s, a); ccdh_full_ctx_decl(s, b); cc_unit p[n]; cc_unit g[n]; cc_unit q[n]; // Bail to errOut when unexpected error happens. // Try all usecases otherwise if((result = ccn_read_uint(n, p, v->pLen, v->p))) goto errOut; if((result = ccn_read_uint(n, g, v->gLen, v->g))) goto errOut; if((result = ccn_read_uint(n, q, v->qLen, v->q))) goto errOut; ccdh_init_gp_with_order(gp, n, p, g, q); ccdh_ctx_init(gp, ccdh_ctx_public(a)); ccdh_ctx_init(gp, ccdh_ctx_public(b)); if((result=ccn_read_uint(n, ccdh_ctx_x(a), v->xaLen, v->xa))) // private key goto errOut; if((result=ccn_read_uint(n, ccdh_ctx_y(a), v->yaLen, v->ya))) // public key goto errOut; if((result=ccn_read_uint(n, ccdh_ctx_x(b), v->xbLen, v->xb))) // private key goto errOut; if((result=ccn_read_uint(n, ccdh_ctx_y(b), v->ybLen, v->yb))) // public key goto errOut; /* * Main test */ /* try one side */ zLen = v->zLen; r1=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng); r1|=!(zLen==v->zLen); r1|=memcmp(z, v->z, zLen); /* try the other side */ zLen = v->zLen; r2=ccdh_compute_shared_secret(b, ccdh_ctx_public(a), &zLen,z,global_test_rng); r2|=!(zLen==v->zLen); r2|=memcmp(z, v->z, zLen); if ((!(r1||r2) && v->valid)||((r1||r2) && !v->valid)) { status|=1<valid) goto doneOut; /* * Corner case / negative testing * Only applicable for valid tests */ /* Output is 1 (use private key is (p-1)/2)*/ if((result=ccn_read_uint(n, ccdh_ctx_x(a), v->pLen, v->p))) // private key goto errOut; ccn_sub1(n,ccdh_ctx_x(a),ccdh_ctx_x(a),1); ccn_shift_right(n,ccdh_ctx_x(a),ccdh_ctx_x(a),1); zLen = v->zLen; if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<xaLen, v->xa))) // restore private key goto errOut; nb_test++; /* negative testing (1 < y < p-1)*/ /* public y = 0 */ zLen = v->zLen; cc_clear(sizeof(tmp),tmp); if((result=ccn_read_uint(n, ccdh_ctx_y(b), zLen, tmp))) { goto errOut; } if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<zLen; cc_clear(sizeof(tmp),tmp); tmp[zLen-1]=1; if((result=ccn_read_uint(n, ccdh_ctx_y(b), zLen, tmp))) { goto errOut; } if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<zLen; if((result=ccn_read_uint(n, ccdh_ctx_y(b), v->pLen, v->p))) goto errOut; if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<zLen; if((result=ccn_read_uint(n, ccdh_ctx_y(b), v->pLen, v->p))) { goto errOut; } ccn_sub1(n,ccdh_ctx_y(b),ccdh_ctx_y(b),1); if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<zLen; if (ccdh_gp_order_bitlen(gp)) { if((result=ccn_read_uint(n, ccdh_ctx_y(b), v->gLen, v->g))) { goto errOut; } ccn_add1(n,ccdh_ctx_y(b),ccdh_ctx_y(b),1); if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<zLen; cc_clear(sizeof(tmp),tmp); tmp[zLen-1]=2; if((result=ccn_read_uint(n, ccdh_ctx_y(b), zLen, tmp))) { goto errOut; } if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))==0) { status|=1<zLen; if((result=ccn_read_uint(n, ccdh_ctx_y(b), v->pLen, v->p))) { goto errOut; } ccn_sub1(n,ccdh_ctx_y(b),ccdh_ctx_y(b),2); if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))==0) { status|=1<zLen; if((result=ccn_read_uint(n, p, v->pLen, v->p))) goto errOut; ccn_set_bit(p,0,0); // Set LS bit to 0 ccdh_init_gp(gp, n, p, g, 0); ccdh_ctx_init(gp, ccdh_ctx_public(a)); ccdh_ctx_init(gp, ccdh_ctx_public(b)); if ((result=ccdh_compute_shared_secret(a, ccdh_ctx_public(b), &zLen,z,global_test_rng))!=0) { status|=1<