summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Makefile3
-rw-r--r--crypto/asn1/a_bitstr.c7
-rw-r--r--crypto/asn1/a_type.c46
-rw-r--r--crypto/asn1/a_verify.c12
-rw-r--r--crypto/asn1/asn1.h3
-rw-r--r--crypto/asn1/asn1_err.c4
-rw-r--r--crypto/asn1/tasn_dec.c8
-rw-r--r--crypto/asn1/x_algor.c10
-rw-r--r--crypto/bn/asm/mips3.s514
-rw-r--r--crypto/bn/asm/x86_64-gcc.c34
-rw-r--r--crypto/bn/bn_asm.c16
-rw-r--r--crypto/bn/bntest.c102
-rw-r--r--crypto/bn/exptest.c11
-rw-r--r--crypto/constant_time_locl.h18
-rw-r--r--crypto/dsa/dsa_asn1.c16
-rw-r--r--crypto/ecdsa/Makefile13
-rw-r--r--crypto/ecdsa/ecs_vrf.c15
-rw-r--r--crypto/evp/Makefile3
-rw-r--r--crypto/evp/evp_enc.c49
-rw-r--r--crypto/md32_common.h6
-rw-r--r--crypto/opensslv.h6
-rw-r--r--crypto/rsa/rsa_oaep.c2
-rw-r--r--crypto/rsa/rsa_pk1.c2
-rw-r--r--crypto/x509/x509.h1
-rw-r--r--crypto/x509/x_all.c2
25 files changed, 529 insertions, 374 deletions
diff --git a/crypto/Makefile b/crypto/Makefile
index c1eb620672f21..6eb8f9101d852 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -41,7 +41,8 @@ SRC= $(LIBSRC)
EXHEADER= crypto.h tmdiff.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
ossl_typ.h
-HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
+HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h \
+ constant_time_locl.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c
index 0fb9ce0c2aea1..665fc09a1dc56 100644
--- a/crypto/asn1/a_bitstr.c
+++ b/crypto/asn1/a_bitstr.c
@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
p= *pp;
i= *(p++);
+ if (i > 7)
+ {
+ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+ goto err;
+ }
/* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate
* on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
+ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c
index 36beceacdb07e..b7a95ad2197cf 100644
--- a/crypto/asn1/a_type.c
+++ b/crypto/asn1/a_type.c
@@ -108,3 +108,49 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
IMPLEMENT_STACK_OF(ASN1_TYPE)
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+ {
+ int result = -1;
+
+ if (!a || !b || a->type != b->type) return -1;
+
+ switch (a->type)
+ {
+ case V_ASN1_OBJECT:
+ result = OBJ_cmp(a->value.object, b->value.object);
+ break;
+ case V_ASN1_NULL:
+ result = 0; /* They do not have content. */
+ break;
+ case V_ASN1_INTEGER:
+ case V_ASN1_NEG_INTEGER:
+ case V_ASN1_ENUMERATED:
+ case V_ASN1_NEG_ENUMERATED:
+ case V_ASN1_BIT_STRING:
+ case V_ASN1_OCTET_STRING:
+ case V_ASN1_SEQUENCE:
+ case V_ASN1_SET:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_VIDEOTEXSTRING:
+ case V_ASN1_IA5STRING:
+ case V_ASN1_UTCTIME:
+ case V_ASN1_GENERALIZEDTIME:
+ case V_ASN1_GRAPHICSTRING:
+ case V_ASN1_VISIBLESTRING:
+ case V_ASN1_GENERALSTRING:
+ case V_ASN1_UNIVERSALSTRING:
+ case V_ASN1_BMPSTRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_OTHER:
+ default:
+ result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
+ (ASN1_STRING *) b->value.ptr);
+ break;
+ }
+
+ return result;
+ }
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 7ded69b170f66..a04aa8b339f8b 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -89,6 +89,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err;
}
+
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+ {
+ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ goto err;
+ }
inl=i2d(data,NULL);
buf_in=OPENSSL_malloc((unsigned int)inl);
@@ -144,6 +150,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
return -1;
}
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ return -1;
+ }
+
EVP_MD_CTX_init(&ctx);
i=OBJ_obj2nid(a->algorithm);
type=EVP_get_digestbyname(OBJ_nid2sn(i));
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index d9d5443a33cab..bd7af2d5099c4 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -769,6 +769,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
int ASN1_TYPE_get(ASN1_TYPE *a);
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
ASN1_OBJECT * ASN1_OBJECT_new(void );
void ASN1_OBJECT_free(ASN1_OBJECT *a);
@@ -1260,6 +1261,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_ILLEGAL_TIME_VALUE 184
#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
+#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
#define ASN1_R_INVALID_DIGIT 130
#define ASN1_R_INVALID_MIME_TYPE 200
@@ -1308,6 +1310,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_TIME_NOT_ASCII_FORMAT 193
#define ASN1_R_TOO_LONG 155
#define ASN1_R_TYPE_NOT_CONSTRUCTED 156
+#define ASN1_R_TYPE_NOT_PRIMITIVE 218
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
#define ASN1_R_UNEXPECTED_EOC 159
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index ba88eb318be3f..92b4f8f100bbe 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -235,6 +235,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
+{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
@@ -283,6 +284,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
{ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
+{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE) ,"type not primitive"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index a228c0d6cd161..b81d151e5fd83 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -866,6 +866,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
}
else if (cst)
{
+ if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+ || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+ || utype == V_ASN1_ENUMERATED)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+ ASN1_R_TYPE_NOT_PRIMITIVE);
+ return 0;
+ }
buf.length = 0;
buf.max = 0;
buf.data = NULL;
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index 99e53429b7979..acc41bacca6e9 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -128,3 +128,13 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
}
}
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+ {
+ int rv;
+ rv = OBJ_cmp(a->algorithm, b->algorithm);
+ if (rv)
+ return rv;
+ if (!a->parameter && !b->parameter)
+ return 0;
+ return ASN1_TYPE_cmp(a->parameter, b->parameter);
+ }
diff --git a/crypto/bn/asm/mips3.s b/crypto/bn/asm/mips3.s
index dca4105c7db1b..8ced51b0ad514 100644
--- a/crypto/bn/asm/mips3.s
+++ b/crypto/bn/asm/mips3.s
@@ -1584,17 +1584,17 @@ LEAF(bn_sqr_comba8)
dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
mflo t_1
mfhi t_2
@@ -1609,63 +1609,63 @@ LEAF(bn_sqr_comba8)
dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt c_3,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu c_3,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
- daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_1,a_2 /* mul_add_c2(a[1],b[2],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
sd c_1,24(a0)
dmultu a_4,a_0 /* mul_add_c2(a[4],b[0],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt c_1,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu c_1,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
- daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_1,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu AT,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
mflo t_1
mfhi t_2
@@ -1680,93 +1680,93 @@ LEAF(bn_sqr_comba8)
dmultu a_0,a_5 /* mul_add_c2(a[0],b[5],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_1,a_4 /* mul_add_c2(a[1],b[4],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_2,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu AT,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_2,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu AT,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
sd c_3,40(a0)
dmultu a_6,a_0 /* mul_add_c2(a[6],b[0],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt c_3,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu c_3,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
- daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_5,a_1 /* mul_add_c2(a[5],b[1],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_4,a_2 /* mul_add_c2(a[4],b[2],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
mflo t_1
mfhi t_2
@@ -1781,108 +1781,108 @@ LEAF(bn_sqr_comba8)
dmultu a_0,a_7 /* mul_add_c2(a[0],b[7],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt c_1,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu c_1,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
- daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_1,a_6 /* mul_add_c2(a[1],b[6],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_1,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu AT,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_2,a_5 /* mul_add_c2(a[2],b[5],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_1,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu AT,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_3,a_4 /* mul_add_c2(a[3],b[4],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_1,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu AT,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
sd c_2,56(a0)
dmultu a_7,a_1 /* mul_add_c2(a[7],b[1],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_6,a_2 /* mul_add_c2(a[6],b[2],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_2,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu AT,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_5,a_3 /* mul_add_c2(a[5],b[3],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_2,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu AT,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_4,a_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */
mflo t_1
mfhi t_2
@@ -1897,78 +1897,78 @@ LEAF(bn_sqr_comba8)
dmultu a_2,a_7 /* mul_add_c2(a[2],b[7],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt c_3,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu c_3,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
- daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_3,a_6 /* mul_add_c2(a[3],b[6],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_4,a_5 /* mul_add_c2(a[4],b[5],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
sd c_1,72(a0)
dmultu a_7,a_3 /* mul_add_c2(a[7],b[3],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt c_1,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu c_1,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
- daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_6,a_4 /* mul_add_c2(a[6],b[4],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_1,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu AT,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_5,a_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */
mflo t_1
mfhi t_2
@@ -1983,48 +1983,48 @@ LEAF(bn_sqr_comba8)
dmultu a_4,a_7 /* mul_add_c2(a[4],b[7],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_5,a_6 /* mul_add_c2(a[5],b[6],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_2,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu AT,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
sd c_3,88(a0)
dmultu a_7,a_5 /* mul_add_c2(a[7],b[5],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt c_3,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu c_3,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
- daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_6,a_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */
mflo t_1
mfhi t_2
@@ -2039,17 +2039,17 @@ LEAF(bn_sqr_comba8)
dmultu a_6,a_7 /* mul_add_c2(a[6],b[7],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt c_1,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu c_1,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
- daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
sd c_2,104(a0)
dmultu a_7,a_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */
@@ -2070,9 +2070,9 @@ LEAF(bn_sqr_comba4)
.set reorder
ld a_0,0(a1)
ld a_1,8(a1)
+ dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
ld a_2,16(a1)
ld a_3,24(a1)
- dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
mflo c_1
mfhi c_2
sd c_1,0(a0)
@@ -2093,17 +2093,17 @@ LEAF(bn_sqr_comba4)
dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
mflo t_1
mfhi t_2
@@ -2118,48 +2118,48 @@ LEAF(bn_sqr_comba4)
dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt c_3,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu c_3,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
- daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
dmultu a_1,a_2 /* mul_add_c(a2[1],b[2],c1,c2,c3); */
mflo t_1
mfhi t_2
- slt AT,t_2,zero
- daddu c_3,AT
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_1,t_1
sltu AT,c_1,t_1
- daddu t_2,AT
+ daddu c_1,t_1
+ daddu AT,t_2
+ sltu t_1,c_1,t_1
+ daddu c_2,AT
+ daddu t_2,t_1
+ sltu AT,c_2,AT
daddu c_2,t_2
- sltu AT,c_2,t_2
daddu c_3,AT
+ sltu t_2,c_2,t_2
+ daddu c_3,t_2
sd c_1,24(a0)
dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
mflo t_1
mfhi t_2
- slt c_1,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_2,t_1
sltu AT,c_2,t_1
- daddu t_2,AT
+ daddu c_2,t_1
+ daddu AT,t_2
+ sltu t_1,c_2,t_1
+ daddu c_3,AT
+ daddu t_2,t_1
+ sltu c_1,c_3,AT
daddu c_3,t_2
- sltu AT,c_3,t_2
- daddu c_1,AT
+ sltu t_2,c_3,t_2
+ daddu c_1,t_2
dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
mflo t_1
mfhi t_2
@@ -2174,17 +2174,17 @@ LEAF(bn_sqr_comba4)
dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
mflo t_1
mfhi t_2
- slt c_2,t_2,zero
- dsll t_2,1
- slt a2,t_1,zero
- daddu t_2,a2
- dsll t_1,1
daddu c_3,t_1
sltu AT,c_3,t_1
- daddu t_2,AT
+ daddu c_3,t_1
+ daddu AT,t_2
+ sltu t_1,c_3,t_1
+ daddu c_1,AT
+ daddu t_2,t_1
+ sltu c_2,c_1,AT
daddu c_1,t_2
- sltu AT,c_1,t_2
- daddu c_2,AT
+ sltu t_2,c_1,t_2
+ daddu c_2,t_2
sd c_3,40(a0)
dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c
index 2d80f192da25a..eba8304f0ae26 100644
--- a/crypto/bn/asm/x86_64-gcc.c
+++ b/crypto/bn/asm/x86_64-gcc.c
@@ -269,6 +269,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+/*
+ * Keep in mind that carrying into high part of multiplication result
+ * can not overflow, because it cannot be all-ones.
+ */
#if 0
/* original macros are kept for reference purposes */
#define mul_add_c(a,b,c0,c1,c2) { \
@@ -283,10 +287,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
BN_ULONG ta=(a),tb=(b),t0; \
t1 = BN_UMULT_HIGH(ta,tb); \
t0 = ta * tb; \
- t2 = t1+t1; c2 += (t2<t1)?1:0; \
- t1 = t0+t0; t2 += (t1<t0)?1:0; \
- c0 += t1; t2 += (c0<t1)?1:0; \
+ c0 += t0; t2 = t1+((c0<t0)?1:0);\
c1 += t2; c2 += (c1<t2)?1:0; \
+ c0 += t0; t1 += (c0<t0)?1:0; \
+ c1 += t1; c2 += (c1<t1)?1:0; \
}
#else
#define mul_add_c(a,b,c0,c1,c2) do { \
@@ -324,22 +328,14 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
: "=a"(t1),"=d"(t2) \
: "a"(a),"m"(b) \
: "cc"); \
- asm ("addq %0,%0; adcq %2,%1" \
- : "+d"(t2),"+r"(c2) \
- : "g"(0) \
- : "cc"); \
- asm ("addq %0,%0; adcq %2,%1" \
- : "+a"(t1),"+d"(t2) \
- : "g"(0) \
- : "cc"); \
- asm ("addq %2,%0; adcq %3,%1" \
- : "+r"(c0),"+d"(t2) \
- : "a"(t1),"g"(0) \
- : "cc"); \
- asm ("addq %2,%0; adcq %3,%1" \
- : "+r"(c1),"+r"(c2) \
- : "d"(t2),"g"(0) \
- : "cc"); \
+ asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
+ : "+r"(c0),"+r"(c1),"+r"(c2) \
+ : "r"(t1),"r"(t2),"g"(0) \
+ : "cc"); \
+ asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
+ : "+r"(c0),"+r"(c1),"+r"(c2) \
+ : "r"(t1),"r"(t2),"g"(0) \
+ : "cc"); \
} while (0)
#endif
diff --git a/crypto/bn/bn_asm.c b/crypto/bn/bn_asm.c
index 99bc2de4913e8..b95b003e15f72 100644
--- a/crypto/bn/bn_asm.c
+++ b/crypto/bn/bn_asm.c
@@ -431,6 +431,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+/*
+ * Keep in mind that carrying into high part of multiplication result
+ * can not overflow, because it cannot be all-ones.
+ */
#ifdef BN_LLONG
#define mul_add_c(a,b,c0,c1,c2) \
t=(BN_ULLONG)a*b; \
@@ -471,10 +475,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
#define mul_add_c2(a,b,c0,c1,c2) { \
BN_ULONG ta=(a),tb=(b),t0; \
BN_UMULT_LOHI(t0,t1,ta,tb); \
- t2 = t1+t1; c2 += (t2<t1)?1:0; \
- t1 = t0+t0; t2 += (t1<t0)?1:0; \
- c0 += t1; t2 += (c0<t1)?1:0; \
+ c0 += t0; t2 = t1+((c0<t0)?1:0);\
c1 += t2; c2 += (c1<t2)?1:0; \
+ c0 += t0; t1 += (c0<t0)?1:0; \
+ c1 += t1; c2 += (c1<t1)?1:0; \
}
#define sqr_add_c(a,i,c0,c1,c2) { \
@@ -501,10 +505,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
BN_ULONG ta=(a),tb=(b),t0; \
t1 = BN_UMULT_HIGH(ta,tb); \
t0 = ta * tb; \
- t2 = t1+t1; c2 += (t2<t1)?1:0; \
- t1 = t0+t0; t2 += (t1<t0)?1:0; \
- c0 += t1; t2 += (c0<t1)?1:0; \
+ c0 += t0; t2 = t1+((c0<t0)?1:0);\
c1 += t2; c2 += (c1<t2)?1:0; \
+ c0 += t0; t1 += (c0<t0)?1:0; \
+ c1 += t1; c2 += (c1<t1)?1:0; \
}
#define sqr_add_c(a,i,c0,c1,c2) { \
diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c
index d41daac5fedb0..9138c2f15ea76 100644
--- a/crypto/bn/bntest.c
+++ b/crypto/bn/bntest.c
@@ -676,44 +676,98 @@ int test_mul(BIO *bp)
int test_sqr(BIO *bp, BN_CTX *ctx)
{
- BIGNUM a,c,d,e;
- int i;
+ BIGNUM *a,*c,*d,*e;
+ int i, ret = 0;
- BN_init(&a);
- BN_init(&c);
- BN_init(&d);
- BN_init(&e);
+ a = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+ if (a == NULL || c == NULL || d == NULL || e == NULL)
+ {
+ goto err;
+ }
for (i=0; i<num0; i++)
{
- BN_bntest_rand(&a,40+i*10,0,0);
- a.neg=rand_neg();
- BN_sqr(&c,&a,ctx);
+ BN_bntest_rand(a,40+i*10,0,0);
+ a->neg=rand_neg();
+ BN_sqr(c,a,ctx);
if (bp != NULL)
{
if (!results)
{
- BN_print(bp,&a);
+ BN_print(bp,a);
BIO_puts(bp," * ");
- BN_print(bp,&a);
+ BN_print(bp,a);
BIO_puts(bp," - ");
}
- BN_print(bp,&c);
+ BN_print(bp,c);
BIO_puts(bp,"\n");
}
- BN_div(&d,&e,&c,&a,ctx);
- BN_sub(&d,&d,&a);
- if(!BN_is_zero(&d) || !BN_is_zero(&e))
- {
- fprintf(stderr,"Square test failed!\n");
- return 0;
- }
+ BN_div(d,e,c,a,ctx);
+ BN_sub(d,d,a);
+ if(!BN_is_zero(d) || !BN_is_zero(e))
+ {
+ fprintf(stderr,"Square test failed!\n");
+ goto err;
+ }
}
- BN_free(&a);
- BN_free(&c);
- BN_free(&d);
- BN_free(&e);
- return(1);
+
+ /* Regression test for a BN_sqr overflow bug. */
+ BN_hex2bn(&a,
+ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
+ BN_sqr(c, a, ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * ");
+ BN_print(bp,a);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(d, a, a, ctx);
+ if (BN_cmp(c, d))
+ {
+ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
+ "different results!\n");
+ goto err;
+ }
+
+ /* Regression test for a BN_sqr overflow bug. */
+ BN_hex2bn(&a,
+ "80000000000000000000000080000001FFFFFFFE000000000000000000000000");
+ BN_sqr(c, a, ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+ BN_print(bp,a);
+ BIO_puts(bp," * ");
+ BN_print(bp,a);
+ BIO_puts(bp," - ");
+ }
+ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+ BN_mul(d, a, a, ctx);
+ if (BN_cmp(c, d))
+ {
+ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
+ "different results!\n");
+ goto err;
+ }
+ ret = 1;
+err:
+ if (a != NULL) BN_free(a);
+ if (c != NULL) BN_free(c);
+ if (d != NULL) BN_free(d);
+ if (e != NULL) BN_free(e);
+ return ret;
}
int test_mont(BIO *bp, BN_CTX *ctx)
diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c
index 44a90e2c8494f..329a05dee2a83 100644
--- a/crypto/bn/exptest.c
+++ b/crypto/bn/exptest.c
@@ -71,6 +71,11 @@
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+/*
+ * Disabled for FIPS capable builds because they use the FIPS BIGNUM library
+ * which will fail this test.
+ */
+#ifndef OPENSSL_FIPS
/* test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. */
static int test_exp_mod_zero() {
BIGNUM a, p, m;
@@ -107,7 +112,7 @@ static int test_exp_mod_zero() {
return ret;
}
-
+#endif
int main(int argc, char *argv[])
{
BN_CTX *ctx;
@@ -228,10 +233,10 @@ int main(int argc, char *argv[])
CRYPTO_mem_leaks(out);
BIO_free(out);
printf("\n");
-
+#ifndef OPENSSL_FIPS
if (test_exp_mod_zero() != 0)
goto err;
-
+#endif
printf("done\n");
EXIT(0);
diff --git a/crypto/constant_time_locl.h b/crypto/constant_time_locl.h
index c0483939fe3db..8af98c168329e 100644
--- a/crypto/constant_time_locl.h
+++ b/crypto/constant_time_locl.h
@@ -129,17 +129,12 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b);
static inline unsigned int constant_time_msb(unsigned int a)
{
- return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
+ return 0-(a >> (sizeof(a) * 8 - 1));
}
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
{
- unsigned int lt;
- /* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
- lt = ~(a ^ b) & (a - b);
- /* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
- lt |= ~a & b;
- return constant_time_msb(lt);
+ return constant_time_msb(a^((a^b)|((a-b)^b)));
}
static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
@@ -149,12 +144,7 @@ static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
{
- unsigned int ge;
- /* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
- ge = ~((a ^ b) | (a - b));
- /* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
- ge |= a & ~b;
- return constant_time_msb(ge);
+ return ~constant_time_lt(a, b);
}
static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
@@ -204,7 +194,7 @@ static inline unsigned char constant_time_select_8(unsigned char mask,
return (unsigned char)(constant_time_select(mask, a, b));
}
-inline int constant_time_select_int(unsigned int mask, int a, int b)
+static inline int constant_time_select_int(unsigned int mask, int a, int b)
{
return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
}
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index bc7d7a02a347d..08d47720fa1e5 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -200,7 +200,11 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int siglen, DSA *dsa)
{
DSA_SIG *s;
+ const unsigned char *p = sigbuf;
+ unsigned char *der = NULL;
+ int derlen = -1;
int ret=-1;
+
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
@@ -211,10 +215,18 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
s = DSA_SIG_new();
if (s == NULL) return(ret);
- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+ if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
+ /* Ensure signature uses DER and doesn't have trailing garbage */
+ derlen = i2d_DSA_SIG(s, &der);
+ if (derlen != siglen || memcmp(sigbuf, der, derlen))
+ goto err;
ret=DSA_do_verify(dgst,dgst_len,s,dsa);
err:
+ if (derlen > 0)
+ {
+ OPENSSL_cleanse(der, derlen);
+ OPENSSL_free(der);
+ }
DSA_SIG_free(s);
return(ret);
}
-
diff --git a/crypto/ecdsa/Makefile b/crypto/ecdsa/Makefile
index 49e2681575a19..6a1b4ef1c0688 100644
--- a/crypto/ecdsa/Makefile
+++ b/crypto/ecdsa/Makefile
@@ -128,11 +128,12 @@ ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ecs_sign.o: ecs_locl.h ecs_sign.c
-ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ecs_vrf.o: ../../e_os.h ../../include/openssl/asn1.h
+ecs_vrf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ecs_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ecs_vrf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ecs_vrf.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+ecs_vrf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ecs_vrf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
ecs_vrf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ecs_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
@@ -140,4 +141,4 @@ ecs_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ecs_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
ecs_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ecs_vrf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-ecs_vrf.o: ecs_locl.h ecs_vrf.c
+ecs_vrf.o: ../cryptlib.h ecs_locl.h ecs_vrf.c
diff --git a/crypto/ecdsa/ecs_vrf.c b/crypto/ecdsa/ecs_vrf.c
index ef9acf7b61028..2836efe5eff22 100644
--- a/crypto/ecdsa/ecs_vrf.c
+++ b/crypto/ecdsa/ecs_vrf.c
@@ -57,6 +57,7 @@
*/
#include "ecs_locl.h"
+#include "cryptlib.h"
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
ECDSA_SIG *s;
+ const unsigned char *p = sigbuf;
+ unsigned char *der = NULL;
+ int derlen = -1;
int ret=-1;
s = ECDSA_SIG_new();
if (s == NULL) return(ret);
- if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
+ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
+ /* Ensure signature uses DER and doesn't have trailing garbage */
+ derlen = i2d_ECDSA_SIG(s, &der);
+ if (derlen != sig_len || memcmp(sigbuf, der, derlen))
+ goto err;
ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
+ if (derlen > 0)
+ {
+ OPENSSL_cleanse(der, derlen);
+ OPENSSL_free(der);
+ }
ECDSA_SIG_free(s);
return(ret);
}
diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
index e5082b714c9d8..c204f84c1d66e 100644
--- a/crypto/evp/Makefile
+++ b/crypto/evp/Makefile
@@ -385,8 +385,7 @@ evp_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
evp_enc.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
evp_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
evp_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-evp_enc.o: ../../include/openssl/x509_vfy.h ../constant_time_locl.h
-evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
+evp_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_enc.c evp_locl.h
evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 0e98e8d156c8f..30e0ca4d9faaf 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -64,7 +64,6 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
-#include "../constant_time_locl.h"
#include "evp_locl.h"
#ifdef OPENSSL_FIPS
@@ -302,11 +301,11 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
- unsigned int i, b;
- unsigned char pad, padding_good;
+ int i,n;
+ unsigned int b;
*outl=0;
- b=(unsigned int)(ctx->cipher->block_size);
+ b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING)
{
if(ctx->buf_len)
@@ -325,34 +324,28 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return(0);
}
OPENSSL_assert(b <= sizeof ctx->final);
- pad=ctx->final[b-1];
-
- padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
- padding_good &= constant_time_ge_8(b, pad);
-
- for (i = 1; i < b; ++i)
+ n=ctx->final[b-1];
+ if (n == 0 || n > (int)b)
{
- unsigned char is_pad_index = constant_time_lt_8(i, pad);
- unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
- padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+ return(0);
}
-
- /*
- * At least 1 byte is always padding, so we always write b - 1
- * bytes to avoid a timing leak. The caller is required to have |b|
- * bytes space in |out| by the API contract.
- */
- for (i = 0; i < b - 1; ++i)
- out[i] = ctx->final[i] & padding_good;
- /* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
- *outl = padding_good & ((unsigned char)(b - pad));
- return padding_good & 1;
+ for (i=0; i<n; i++)
+ {
+ if (ctx->final[--b] != n)
+ {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+ return(0);
+ }
+ }
+ n=ctx->cipher->block_size-n;
+ for (i=0; i<n; i++)
+ out[i]=ctx->final[i];
+ *outl=n;
}
else
- {
- *outl = 0;
- return 1;
- }
+ *outl=0;
+ return(1);
}
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
diff --git a/crypto/md32_common.h b/crypto/md32_common.h
index e0deb78015a52..486d6ca6f4e36 100644
--- a/crypto/md32_common.h
+++ b/crypto/md32_common.h
@@ -225,8 +225,7 @@
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \
- l|=(((unsigned long)(*((c)++))) ), \
- l)
+ l|=(((unsigned long)(*((c)++))) ) )
#endif
#ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
@@ -262,8 +261,7 @@
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \
- l|=(((unsigned long)(*((c)++)))<<24), \
- l)
+ l|=(((unsigned long)(*((c)++)))<<24) )
#endif
#ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index 50001f32f925f..e05914e05f95b 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x009081cfL
+#define OPENSSL_VERSION_NUMBER 0x009081dfL
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zc-fips 15 Oct 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zd-fips 8 Jan 2015"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zc 15 Oct 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zd 8 Jan 2015"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index 97ea8b6c6693c..67a7ace7fe528 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -18,7 +18,7 @@
* an equivalent notion.
*/
-#include "../constant_time_locl.h"
+#include "constant_time_locl.h"
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
#include <stdio.h>
diff --git a/crypto/rsa/rsa_pk1.c b/crypto/rsa/rsa_pk1.c
index e028ff7189e0c..c2da56f6cad8f 100644
--- a/crypto/rsa/rsa_pk1.c
+++ b/crypto/rsa/rsa_pk1.c
@@ -56,7 +56,7 @@
* [including the GNU Public Licence.]
*/
-#include "../constant_time_locl.h"
+#include "constant_time_locl.h"
#include <stdio.h>
#include "cryptlib.h"
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index c34689a1b389a..e77ee691066ce 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -870,6 +870,7 @@ X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
X509_NAME *X509_NAME_dup(X509_NAME *xn);
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index c7b07f7c9d58d..f4c68fc17c23f 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -73,6 +73,8 @@
int X509_verify(X509 *a, EVP_PKEY *r)
{
+ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+ return 0;
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
a->signature,a->cert_info,r));
}