Permalink
Browse files

Make explicit _ct and _nonct versions of bn_mod_exp funcitons that

matter for constant time, and make the public interface only used
external to the library.

This moves us to a model where the important things are constant time
versions unless you ask for them not to be, rather than the opposite.
I'll continue with this method by method.

Add regress tests for same.
ok jsing@
  • Loading branch information...
beck
beck committed Jan 21, 2017
1 parent e447a03 commit 952c1252f58f5f57227f5efaeec0169759c77d72
@@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.13 2016/12/21 15:49:29 jsing Exp $
# $OpenBSD: Makefile,v 1.14 2017/01/21 09:38:58 beck Exp $
LIB= crypto
@@ -24,7 +24,8 @@ CFLAGS+= -DLIBRESSL_INTERNAL
CFLAGS+= -DOPENSSL_NO_HW_PADLOCK # XXX enable this?
CFLAGS+= -I${LCRYPTO_SRC}
CFLAGS+= -I${LCRYPTO_SRC}/modes -I${LCRYPTO_SRC}/asn1 -I${LCRYPTO_SRC}/evp
CFLAGS+= -I${LCRYPTO_SRC}/asn1 -I${LCRYPTO_SRC}/bn -I${LCRYPTO_SRC}/evp
CFLAGS+= -I${LCRYPTO_SRC}/modes
VERSION_SCRIPT= Symbols.map
SYMBOL_LIST= ${.CURDIR}/Symbols.list
@@ -1,4 +1,4 @@
/* $OpenBSD: bn.h,v 1.32 2016/12/21 15:49:29 jsing Exp $ */
/* $OpenBSD: bn.h,v 1.33 2017/01/21 09:38:58 beck Exp $ */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -418,10 +418,12 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
int BN_lshift1(BIGNUM *r, const BIGNUM *a);
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
#ifndef LIBRESSL_INTERNAL
int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx);
int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
#endif
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
@@ -1,4 +1,4 @@
/* $OpenBSD: bn_blind.c,v 1.14 2014/07/12 16:03:36 miod Exp $ */
/* $OpenBSD: bn_blind.c,v 1.15 2017/01/21 09:38:58 beck Exp $ */
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
@@ -372,7 +372,7 @@ BN_BLINDING_create_param(BN_BLINDING *b, const BIGNUM *e, BIGNUM *m,
ctx, ret->m_ctx))
goto err;
} else {
if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
if (!BN_mod_exp_ct(ret->A, ret->A, ret->e, ret->mod, ctx))
goto err;
}
@@ -1,4 +1,4 @@
/* $OpenBSD: bn_exp.c,v 1.27 2017/01/21 04:34:16 beck Exp $ */
/* $OpenBSD: bn_exp.c,v 1.28 2017/01/21 09:38:58 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -172,9 +172,9 @@ BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
return (ret);
}
int
BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
static int
BN_mod_exp_internal(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, int ct)
{
int ret;
@@ -213,12 +213,11 @@ BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
*/
if (BN_is_odd(m)) {
if (a->top == 1 && !a->neg &&
(BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
if (a->top == 1 && !a->neg && !ct) {
BN_ULONG A = a->d[0];
ret = BN_mod_exp_mont_word(r, A,p, m,ctx, NULL);
} else
ret = BN_mod_exp_mont(r, a,p, m,ctx, NULL);
ret = BN_mod_exp_mont_ct(r, a,p, m,ctx, NULL);
} else {
ret = BN_mod_exp_recp(r, a,p, m, ctx);
}
@@ -227,6 +226,30 @@ BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
return (ret);
}
int
BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
{
return BN_mod_exp_internal(r, a, p, m, ctx,
(BN_get_flags(p, BN_FLG_CONSTTIME) != 0));
}
int
BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
{
return BN_mod_exp_internal(r, a, p, m, ctx, 1);
}
int
BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
{
return BN_mod_exp_internal(r, a, p, m, ctx, 0);
}
int
BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
@@ -361,9 +384,9 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
return (ret);
}
int
BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont)
static int
BN_mod_exp_mont_internal(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont, int ct)
{
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
int start = 1;
@@ -373,7 +396,7 @@ BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BIGNUM *val[TABLE_SIZE];
BN_MONT_CTX *mont = NULL;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
if (ct) {
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
}
@@ -513,6 +536,27 @@ BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
return (ret);
}
int
BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont,
(BN_get_flags(p, BN_FLG_CONSTTIME) != 0));
}
int
BN_mod_exp_mont_ct(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont, 1);
}
int
BN_mod_exp_mont_nonct(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
return BN_mod_exp_mont_internal(rr, a, p, m, ctx, in_mont, 0);
}
/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
* so that accessing any of these table values shows the same access pattern as far
@@ -1,4 +1,4 @@
/* $OpenBSD: bn_lcl.h,v 1.23 2016/12/21 15:49:29 jsing Exp $ */
/* $OpenBSD: bn_lcl.h,v 1.24 2017/01/21 09:38:58 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -584,6 +584,16 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int
int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
/* Explicitly const time / non-const time versions for internal use */
int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx);
int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx);
int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
__END_HIDDEN_DECLS
#endif
@@ -1,4 +1,4 @@
/* $OpenBSD: bn_prime.c,v 1.15 2016/07/05 02:54:35 bcook Exp $ */
/* $OpenBSD: bn_prime.c,v 1.16 2017/01/21 09:38:58 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -369,7 +369,7 @@ static int
witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, const BIGNUM *a1_odd,
int k, BN_CTX *ctx, BN_MONT_CTX *mont)
{
if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont))
if (!BN_mod_exp_mont_ct(w, w, a1_odd, a, ctx, mont))
/* w := w^a1_odd mod a */
return -1;
if (BN_is_one(w))
@@ -1,4 +1,4 @@
/* $OpenBSD: bn_sqrt.c,v 1.7 2016/11/08 01:40:22 guenther Exp $ */
/* $OpenBSD: bn_sqrt.c,v 1.8 2017/01/21 09:38:58 beck Exp $ */
/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* and Bodo Moeller for the OpenSSL project. */
/* ====================================================================
@@ -149,7 +149,7 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
q->neg = 0;
if (!BN_add_word(q, 1))
goto end;
if (!BN_mod_exp(ret, A, q, p, ctx))
if (!BN_mod_exp_ct(ret, A, q, p, ctx))
goto end;
err = 0;
goto vrfy;
@@ -190,7 +190,7 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
if (!BN_rshift(q, p, 3))
goto end;
q->neg = 0;
if (!BN_mod_exp(b, t, q, p, ctx))
if (!BN_mod_exp_ct(b, t, q, p, ctx))
goto end;
/* y := b^2 */
@@ -272,7 +272,7 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
/* Now that we have some non-square, we can find an element
* of order 2^e by computing its q'th power. */
if (!BN_mod_exp(y, y, q, p, ctx))
if (!BN_mod_exp_ct(y, y, q, p, ctx))
goto end;
if (BN_is_one(y)) {
BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
@@ -314,7 +314,7 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
} else if (!BN_one(x))
goto end;
} else {
if (!BN_mod_exp(x, A, t, p, ctx))
if (!BN_mod_exp_ct(x, A, t, p, ctx))
goto end;
if (BN_is_zero(x)) {
/* special case: a == 0 (mod p) */
@@ -1,4 +1,4 @@
/* $OpenBSD: dh_key.c,v 1.25 2016/07/07 11:53:12 bcook Exp $ */
/* $OpenBSD: dh_key.c,v 1.26 2017/01/21 09:38:58 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -62,6 +62,8 @@
#include <openssl/dh.h>
#include <openssl/err.h>
#include "bn_lcl.h"
static int generate_key(DH *dh);
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a,
@@ -233,7 +235,7 @@ static int
dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
{
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
return BN_mod_exp_mont_ct(r, a, p, m, ctx, m_ctx);
}
static int
@@ -1,4 +1,4 @@
/* $OpenBSD: dsa_ameth.c,v 1.20 2016/10/19 16:49:11 jsing Exp $ */
/* $OpenBSD: dsa_ameth.c,v 1.21 2017/01/21 09:38:59 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
@@ -66,8 +66,8 @@
#include <openssl/err.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "bn_lcl.h"
static int
dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
@@ -224,7 +224,7 @@ dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
goto dsaerr;
}
if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
goto dsaerr;
}
@@ -1,4 +1,4 @@
/* $OpenBSD: dsa_gen.c,v 1.22 2015/07/15 18:34:37 miod Exp $ */
/* $OpenBSD: dsa_gen.c,v 1.23 2017/01/21 09:38:59 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -68,6 +68,7 @@
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "bn_lcl.h"
#include "dsa_locl.h"
int
@@ -315,7 +316,7 @@ dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd,
for (;;) {
/* g=test^r0%p */
if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
if (!BN_mod_exp_mont_ct(g, test, r0, p, ctx, mont))
goto err;
if (!BN_is_one(g))
break;
@@ -1,4 +1,4 @@
/* $OpenBSD: dsa_key.c,v 1.22 2016/06/30 02:02:06 bcook Exp $ */
/* $OpenBSD: dsa_key.c,v 1.23 2017/01/21 09:38:59 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,6 +65,7 @@
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include "bn_lcl.h"
static int dsa_builtin_keygen(DSA *dsa);
@@ -108,7 +109,7 @@ dsa_builtin_keygen(DSA *dsa)
BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx))
if (!BN_mod_exp_ct(pub_key, dsa->g, &prk, dsa->p, ctx))
goto err;
}
@@ -1,4 +1,4 @@
/* $OpenBSD: dsa_ossl.c,v 1.26 2016/06/21 04:16:53 bcook Exp $ */
/* $OpenBSD: dsa_ossl.c,v 1.27 2017/01/21 09:38:59 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,8 @@
#include <openssl/err.h>
#include <openssl/sha.h>
#include "bn_lcl.h"
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
@@ -238,7 +240,7 @@ dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
dsa->method_mont_p))
goto err;
} else {
if (!BN_mod_exp_mont(r, dsa->g, &k, dsa->p, ctx, dsa->method_mont_p))
if (!BN_mod_exp_mont_ct(r, dsa->g, &k, dsa->p, ctx, dsa->method_mont_p))
goto err;
}
@@ -1,4 +1,4 @@
/* $OpenBSD: pvkfmt.c,v 1.16 2016/03/02 14:28:14 beck Exp $ */
/* $OpenBSD: pvkfmt.c,v 1.17 2017/01/21 09:38:59 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2005.
*/
@@ -73,6 +73,8 @@
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include "bn_lcl.h"
/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
* format
*/
@@ -340,7 +342,7 @@ b2i_dss(const unsigned char **in, unsigned int length, unsigned int bitlen,
goto memerr;
if (!(ctx = BN_CTX_new()))
goto memerr;
if (!BN_mod_exp(dsa->pub_key, dsa->g,
if (!BN_mod_exp_ct(dsa->pub_key, dsa->g,
dsa->priv_key, dsa->p, ctx))
goto memerr;
BN_CTX_free(ctx);
Oops, something went wrong.

0 comments on commit 952c125

Please sign in to comment.