/*
- * Copyright 2002-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <limits.h>
#include <stdio.h>
#include "internal/cryptlib.h"
-#include "bn_lcl.h"
+#include "bn_local.h"
#ifndef OPENSSL_NO_EC2M
*/
# define MAX_ITERATIONS 50
-static const BN_ULONG SQR_tb[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
- 64, 65, 68, 69, 80, 81, 84, 85
-};
+# define SQR_nibble(w) ((((w) & 8) << 3) \
+ | (((w) & 4) << 2) \
+ | (((w) & 2) << 1) \
+ | ((w) & 1))
+
/* Platform-specific macros to accelerate squaring. */
# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
# define SQR1(w) \
- SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
- SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
- SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
- SQR_tb[(w) >> 36 & 0xF] << 8 | SQR_tb[(w) >> 32 & 0xF]
+ SQR_nibble((w) >> 60) << 56 | SQR_nibble((w) >> 56) << 48 | \
+ SQR_nibble((w) >> 52) << 40 | SQR_nibble((w) >> 48) << 32 | \
+ SQR_nibble((w) >> 44) << 24 | SQR_nibble((w) >> 40) << 16 | \
+ SQR_nibble((w) >> 36) << 8 | SQR_nibble((w) >> 32)
# define SQR0(w) \
- SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
- SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
- SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
- SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
+ SQR_nibble((w) >> 28) << 56 | SQR_nibble((w) >> 24) << 48 | \
+ SQR_nibble((w) >> 20) << 40 | SQR_nibble((w) >> 16) << 32 | \
+ SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \
+ SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) )
# endif
# ifdef THIRTY_TWO_BIT
# define SQR1(w) \
- SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
- SQR_tb[(w) >> 20 & 0xF] << 8 | SQR_tb[(w) >> 16 & 0xF]
+ SQR_nibble((w) >> 28) << 24 | SQR_nibble((w) >> 24) << 16 | \
+ SQR_nibble((w) >> 20) << 8 | SQR_nibble((w) >> 16)
# define SQR0(w) \
- SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
- SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
+ SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \
+ SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) )
# endif
# if !defined(OPENSSL_BN_ASM_GF2m)
* Hernandez, J.L., and Menezes, A. "Software Implementation of Elliptic
* Curve Cryptography Over Binary Fields".
*/
-int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+static int BN_GF2m_mod_inv_vartime(BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, BN_CTX *ctx)
{
BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
int ret = 0;
return ret;
}
+/*-
+ * Wrapper for BN_GF2m_mod_inv_vartime that blinds the input before calling.
+ * This is not constant time.
+ * But it does eliminate first order deduction on the input.
+ */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+ BIGNUM *b = NULL;
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+ if ((b = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ /* generate blinding value */
+ do {
+ if (!BN_priv_rand_ex(b, BN_num_bits(p) - 1,
+ BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx))
+ goto err;
+ } while (BN_is_zero(b));
+
+ /* r := a * b */
+ if (!BN_GF2m_mod_mul(r, a, b, p, ctx))
+ goto err;
+
+ /* r := 1/(a * b) */
+ if (!BN_GF2m_mod_inv_vartime(r, r, p, ctx))
+ goto err;
+
+ /* r := b/(a * b) = 1/a */
+ if (!BN_GF2m_mod_mul(r, r, b, p, ctx))
+ goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
/*
* Invert xx, reduce modulo p, and store the result in r. r could be xx.
* This function calls down to the BN_GF2m_mod_inv implementation; this
return ret;
}
-# ifndef OPENSSL_SUN_GF2M_DIV
/*
* Divide y by x, reduce modulo p, and store the result in r. r could be x
* or y, x could equal y.
BN_CTX_end(ctx);
return ret;
}
-# else
-/*
- * Divide y by x, reduce modulo p, and store the result in r. r could be x
- * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from
- * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to the
- * Great Divide".
- */
-int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
- const BIGNUM *p, BN_CTX *ctx)
-{
- BIGNUM *a, *b, *u, *v;
- int ret = 0;
-
- bn_check_top(y);
- bn_check_top(x);
- bn_check_top(p);
-
- BN_CTX_start(ctx);
-
- a = BN_CTX_get(ctx);
- b = BN_CTX_get(ctx);
- u = BN_CTX_get(ctx);
- v = BN_CTX_get(ctx);
- if (v == NULL)
- goto err;
-
- /* reduce x and y mod p */
- if (!BN_GF2m_mod(u, y, p))
- goto err;
- if (!BN_GF2m_mod(a, x, p))
- goto err;
- if (!BN_copy(b, p))
- goto err;
-
- while (!BN_is_odd(a)) {
- if (!BN_rshift1(a, a))
- goto err;
- if (BN_is_odd(u))
- if (!BN_GF2m_add(u, u, p))
- goto err;
- if (!BN_rshift1(u, u))
- goto err;
- }
-
- do {
- if (BN_GF2m_cmp(b, a) > 0) {
- if (!BN_GF2m_add(b, b, a))
- goto err;
- if (!BN_GF2m_add(v, v, u))
- goto err;
- do {
- if (!BN_rshift1(b, b))
- goto err;
- if (BN_is_odd(v))
- if (!BN_GF2m_add(v, v, p))
- goto err;
- if (!BN_rshift1(v, v))
- goto err;
- } while (!BN_is_odd(b));
- } else if (BN_abs_is_word(a, 1))
- break;
- else {
- if (!BN_GF2m_add(a, a, b))
- goto err;
- if (!BN_GF2m_add(u, u, v))
- goto err;
- do {
- if (!BN_rshift1(a, a))
- goto err;
- if (BN_is_odd(u))
- if (!BN_GF2m_add(u, u, p))
- goto err;
- if (!BN_rshift1(u, u))
- goto err;
- } while (!BN_is_odd(a));
- }
- } while (1);
-
- if (!BN_copy(r, u))
- goto err;
- bn_check_top(r);
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- return ret;
-}
-# endif
/*
* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
bn_check_top(b);
if (BN_is_zero(b))
- return (BN_one(r));
+ return BN_one(r);
if (BN_abs_is_word(b, 1))
return (BN_copy(r, a) != NULL);
if (tmp == NULL)
goto err;
do {
- if (!BN_priv_rand(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+ if (!BN_priv_rand_ex(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY,
+ ctx))
goto err;
if (!BN_GF2m_mod_arr(rho, rho, p))
goto err;