diff options
Diffstat (limited to 'test/tpm_test/bn_test.c')
-rw-r--r-- | test/tpm_test/bn_test.c | 412 |
1 files changed, 0 insertions, 412 deletions
diff --git a/test/tpm_test/bn_test.c b/test/tpm_test/bn_test.c deleted file mode 100644 index db06ee93d4..0000000000 --- a/test/tpm_test/bn_test.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "dcrypto.h" - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/param.h> - -#include <openssl/bn.h> - -/** - * Compatibility layer for OpenSSL 1.0.x. - * BN_bn2lebinpad and BN_lebin2bn were added in OpenSSL 1.1, to provide - * import/export functionality as BIGNUM struct became opaque. - */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#define BN_RAND_TOP_ANY -1 -#define BN_RAND_TOP_ONE 0 -#define BN_RAND_TOP_TWO 1 -#define BN_RAND_BOTTOM_ODD 1 -#define BN_RAND_BOTTOM_ANY 0 - -/* export BIGNUM as little-endian padded to tolen bytes binary */ -static int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) -{ - int i; - BN_ULONG l; - - bn_check_top(a); - i = BN_num_bytes(a); - if (tolen < i) - return -1; - /* Add trailing zeroes if necessary */ - if (tolen > i) - memset(to + i, 0, tolen - i); - to += i; - while (i--) { - l = a->d[i / BN_BYTES]; - to--; - *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; - } - return tolen; -} - -/* import BIGNUM from little-endian binary of specified length */ -static BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) -{ - unsigned int i, m; - unsigned int n; - BN_ULONG l; - BIGNUM *bn = NULL; - - if (ret == NULL) - ret = bn = BN_new(); - if (ret == NULL) - return (NULL); - bn_check_top(ret); - s += len; - /* Skip trailing zeroes. */ - for (; len > 0 && s[-1] == 0; s--, len--) - continue; - n = len; - if (n == 0) { - ret->top = 0; - return ret; - } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (bn_wexpand(ret, (int)i) == NULL) { - BN_free(bn); - return NULL; - } - ret->top = i; - ret->neg = 0; - l = 0; - while (n--) { - s--; - l = (l << 8L) | *s; - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; - } - } - /* - * need to call this due to clear byte at top if avoiding - * having the top bit set (-ve number) - */ - bn_correct_top(ret); - return ret; -} -#endif - -#define MAX_BN_TEST_SIZE 2048 - -static char to_hexchar(unsigned char c) -{ - return (c < 10) ? c + '0' : c - 10 + 'A'; -} - -static void hex_print(FILE *fp, unsigned char *d, int size) -{ - char buf[MAX_BN_TEST_SIZE / 4 + 1]; - int i = 0; - - assert((size * 2) + 1 <= sizeof(buf)); - while (i < size) { - buf[i * 2] = to_hexchar((d[size - i - 1] >> 4) & 0xF); - buf[i * 2 + 1] = to_hexchar(d[size - i - 1] & 0xF); - i++; - }; - buf[size * 2] = 0; - fprintf(fp, buf); -} - -static void dcrypto_print(FILE *fp, struct LITE_BIGNUM *d, int size) -{ - hex_print(fp, (unsigned char *)d->d, size); -} - -static int bn_dcrypto_cmpeq(const BIGNUM *b, struct LITE_BIGNUM *d) -{ - unsigned char buf[MAX_BN_TEST_SIZE / 8]; - int size = BN_num_bytes(b); - - assert(size <= sizeof(buf)); - BN_bn2lebinpad(b, buf, size); - return memcmp(d->d, buf, size); -} - -/* Convert OpenSSL BIGNUM to Dcrypto, assumes caller provides buffer */ -static void bn_to_dcrypto(const BIGNUM *b, struct LITE_BIGNUM *d, uint32_t *buf, - size_t bufsize) -{ - int bn_size = BN_num_bytes(b); - - assert(bn_size <= bufsize); - memset(buf, 0, bufsize); - /** - * OpenSSL 1.0 was only working for little-endian architectures (x86) - * and had direct access to BIGNUM structure, so DCRYPTO_bn_wrap which - * just sets a pointer to user provided buffer as source for - * LITE_BIGNUM could be applied to data in BIGNUM as is. - * In OpenSSL 1.1 BIGNUM became opaque, so we need to export binary - * to get data in little-endian format which used by DCRYPTO_*. - */ - BN_bn2lebinpad(b, (unsigned char *)buf, bn_size); - DCRYPTO_bn_wrap(d, buf, bufsize); -} - -static int test_bn_modinv_helper(const BIGNUM *E, BN_CTX *ctx, int mod_top, - int mod_bottom) -{ - int i, result = 0; - BIGNUM *MOD, *r; - - BN_CTX_start(ctx); - MOD = BN_CTX_get(ctx); - r = BN_CTX_get(ctx); - - for (i = 0; i < 1000; i++) { - uint32_t m_buf[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - uint32_t d_buf[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - uint32_t e_buf[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - int has_inverse; - int test_inverse; - - struct LITE_BIGNUM m; - struct LITE_BIGNUM e; - struct LITE_BIGNUM d; - - /* Top bit set, bottom bit clear. */ - BN_rand(MOD, MAX_BN_TEST_SIZE, mod_top, mod_bottom); - - if (BN_mod_inverse(r, E, MOD, ctx)) - has_inverse = 1; - else - has_inverse = 0; - bn_to_dcrypto(MOD, &m, m_buf, sizeof(m_buf)); - bn_to_dcrypto(E, &e, e_buf, sizeof(e_buf)); - - bn_init(&d, d_buf, sizeof(d_buf)); - - test_inverse = bn_modinv_vartime(&d, &e, &m); - - if (test_inverse != has_inverse) { - fprintf(stderr, - "ossl inverse: %d, dcrypto inverse: %d\n", - has_inverse, test_inverse); - fprintf(stderr, "d : "); - BN_print_fp(stderr, r); - fprintf(stderr, "\n"); - - fprintf(stderr, "e : "); - BN_print_fp(stderr, E); - fprintf(stderr, "\n"); - - fprintf(stderr, "M : "); - BN_print_fp(stderr, MOD); - fprintf(stderr, "\n"); - result = 1; - goto fail; - } - - if (has_inverse) { - if (bn_dcrypto_cmpeq(r, &d) != 0) { - fprintf(stderr, - "dcrypto bn_modinv_vartime fail\n"); - fprintf(stderr, "d : "); - BN_print_fp(stderr, r); - fprintf(stderr, "\n dd: "); - dcrypto_print(stderr, &d, BN_num_bytes(r)); - fprintf(stderr, "\n"); - - fprintf(stderr, "e : "); - BN_print_fp(stderr, E); - fprintf(stderr, "\n"); - - fprintf(stderr, "M : "); - BN_print_fp(stderr, MOD); - fprintf(stderr, "\n"); - - result = 1; - goto fail; - } - } - } -fail: - BN_CTX_end(ctx); - return result; -} - -static int test_bn_modinv(void) -{ - BN_CTX *ctx; - BIGNUM *E; - int result = 1; - - ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - E = BN_CTX_get(ctx); - - BN_rand(E, 1024, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD); - /* Top bit set, bottom bit clear. */ - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto fail; - - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) - goto fail; - - BN_rand(E, 32, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD); - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto fail; - - BN_rand(E, 17, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ODD); - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto fail; - - BN_set_word(E, 3); - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto fail; - - BN_set_word(E, 65537); - if (test_bn_modinv_helper(E, ctx, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto fail; - - result = 0; -fail: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return result; -} - -/* Build a BIGNUM with following template: - * 11111111111111110000001111111111111000000000000123455667 - * size - size in bits - * front_ones mid_ones_pos,mid_ones, rand_low - * front_ones - number of 1 bits in highest position - * mid_ones_pos - starting position of middle ones - * mid_ones - number of 1 bits in the middle - * rand_low - number of random low bits - */ -static BIGNUM *bn_gen(BIGNUM *out, int size, int front_ones, int mid_ones_pos, - int mid_ones, int rand_low) -{ - unsigned char n[MAX_BN_TEST_SIZE / 8] = {}; - - assert(size <= sizeof(n) * 8); - assert(front_ones < size); - assert(mid_ones_pos < (size - front_ones - 1)); - assert(mid_ones < (size - mid_ones_pos - 1)); - assert(rand_low < (size - mid_ones_pos - mid_ones - 1)); - /* generate little-endian representation */ - while (front_ones) { - n[(size - front_ones) / 8] |= 1 << ((size - front_ones) & 7); - front_ones--; - } - while (mid_ones) { - n[(mid_ones_pos - mid_ones) / 8] |= - 1 << ((mid_ones_pos - mid_ones) & 7); - mid_ones--; - } - while (rand_low) { - n[(rand_low - 1) / 8] |= (rand() & 1) << ((rand_low - 1) & 7); - rand_low--; - } - - return BN_lebin2bn(n, size / 8, out); -} - -static int test_bn_div(void) -{ - const int NSIZE = MAX_BN_TEST_SIZE; - const int PSIZE = MAX_BN_TEST_SIZE / 2; - BIGNUM *N, *P, *Q, *R; - BN_CTX *ctx; - int result = 0, total = 0, prev = 1; - int nf, nmps, nms, pf, pmps, pms; - struct LITE_BIGNUM p; - struct LITE_BIGNUM q; - struct LITE_BIGNUM n; - struct LITE_BIGNUM r; - - uint32_t p_buff[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - uint32_t q_buff[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - uint32_t n_buff[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - uint32_t r_buff[MAX_BN_TEST_SIZE / LITE_BN_BITS2]; - - ctx = BN_CTX_new(); - BN_CTX_start(ctx); - N = BN_CTX_get(ctx); - P = BN_CTX_get(ctx); - Q = BN_CTX_get(ctx); - R = BN_CTX_get(ctx); - - for (nf = 1; nf <= NSIZE / 8; nf++) - for (nmps = NSIZE / 16; nmps < (NSIZE / 16) + 2; nmps++) - for (nms = NSIZE / 32; nms < (NSIZE / 32) + 2; nms++) { - N = bn_gen(N, NSIZE, nf, nmps, nms, (nmps - nms) / 2); - for (pf = 1; pf <= PSIZE / 4; pf++) - for (pmps = PSIZE / 16; pmps < (PSIZE / 16) + 2; pmps++) - for (pms = PSIZE / 32; pms < (PSIZE / 32) + 2; pms++) { - P = bn_gen(P, PSIZE, pf, pmps, pms, (pmps - pms) / 2); - total++; - bn_to_dcrypto(N, &n, n_buff, sizeof(n_buff)); - bn_to_dcrypto(P, &p, p_buff, sizeof(p_buff)); - DCRYPTO_bn_wrap(&q, q_buff, sizeof(q_buff)); - DCRYPTO_bn_wrap(&r, r_buff, sizeof(r_buff)); - - BN_div(Q, R, N, P, ctx); - DCRYPTO_bn_div(&q, &r, &n, &p); - - if ((bn_dcrypto_cmpeq(Q, &q) != 0) || - (bn_dcrypto_cmpeq(R, &r) != 0)) { - result++; - if (result > prev) { - /* print only 1 sample in 100000 */ - prev = result + 100000; - fprintf(stderr, "N : "); - BN_print_fp(stderr, N); - fprintf(stderr, "\n"); - fprintf(stderr, "P : "); - BN_print_fp(stderr, P); - fprintf(stderr, "\n"); - - fprintf(stderr, "Q : "); - BN_print_fp(stderr, Q); - fprintf(stderr, "\nQd: "); - dcrypto_print(stderr, &q, - BN_num_bytes(Q)); - fprintf(stderr, "\n"); - - fprintf(stderr, "R : "); - BN_print_fp(stderr, R); - fprintf(stderr, "\nRd: "); - dcrypto_print(stderr, &r, - BN_num_bytes(R)); - fprintf(stderr, "\n"); - } - } - } - } - if (result) - fprintf(stderr, "DCRYPTO_bn_div: total=%d, failures=%d\n", - total, result); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - - return result; -} - -void *always_memset(void *s, int c, size_t n) -{ - memset(s, c, n); - return s; -} - -void watchdog_reload(void) -{ -} - -int main(void) -{ - assert(test_bn_modinv() == 0); - assert(test_bn_div() == 0); - fprintf(stderr, "PASS\n"); - return 0; -} |