Merge pull request #33558 from akien-mga/3.0-openssl-1.0.2t

openssl: Update to pristine 1.0.2t (security update)
This commit is contained in:
Rémi Verschelde 2019-11-12 09:48:12 +01:00 committed by GitHub
commit 8c73f79492
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 686 additions and 167 deletions

View File

@ -225,6 +225,7 @@ Important: The files `utils/bit_reader_utils.{c,h}` have Godot-made
changes to ensure they build for Javascript/HTML5. Those changes to ensure they build for Javascript/HTML5. Those
changes are marked with `// -- GODOT --` comments. changes are marked with `// -- GODOT --` comments.
## minizip ## minizip
- Upstream: http://www.zlib.net - Upstream: http://www.zlib.net
@ -326,7 +327,7 @@ Files extracted from the upstream source:
## openssl ## openssl
- Upstream: https://www.openssl.org - Upstream: https://www.openssl.org
- Version: 1.0.2s - Version: 1.0.2t
- License: OpenSSL license / BSD-like - License: OpenSSL license / BSD-like
Files extracted from the upstream source: Files extracted from the upstream source:

View File

@ -64,7 +64,7 @@
# endif # endif
# endif # endif
# if !__ASSEMBLER__ # ifndef __ASSEMBLER__
extern unsigned int OPENSSL_armcap_P; extern unsigned int OPENSSL_armcap_P;
# endif # endif

View File

@ -5,6 +5,7 @@
#include <signal.h> #include <signal.h>
#include <crypto.h> #include <crypto.h>
#include "cryptlib.h"
#include "arm_arch.h" #include "arm_arch.h"
unsigned int OPENSSL_armcap_P = 0; unsigned int OPENSSL_armcap_P = 0;

View File

@ -66,6 +66,7 @@
#include <stdio.h> #include <stdio.h>
#include "cryptlib.h" #include "cryptlib.h"
#include "bn_lcl.h" #include "bn_lcl.h"
#include "constant_time_locl.h"
const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT; const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT;
@ -187,13 +188,57 @@ int BN_num_bits_word(BN_ULONG l)
return bits; return bits;
} }
/*
* This function still leaks `a->dmax`: it's caller's responsibility to
* expand the input `a` in advance to a public length.
*/
static inline
int bn_num_bits_consttime(const BIGNUM *a)
{
int j, ret;
unsigned int mask, past_i;
int i = a->top - 1;
bn_check_top(a);
for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) {
mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */
ret += BN_BITS2 & (~mask & ~past_i);
ret += BN_num_bits_word(a->d[j]) & mask;
past_i |= mask; /* past_i will become 0xff..ff after i==j */
}
/*
* if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the
* final result.
*/
mask = ~(constant_time_eq_int(i, ((int)-1)));
return ret & mask;
}
int BN_num_bits(const BIGNUM *a) int BN_num_bits(const BIGNUM *a)
{ {
int i = a->top - 1; int i = a->top - 1;
bn_check_top(a); bn_check_top(a);
if (a->flags & BN_FLG_CONSTTIME) {
/*
* We assume that BIGNUMs flagged as CONSTTIME have also been expanded
* so that a->dmax is not leaking secret information.
*
* In other words, it's the caller's responsibility to ensure `a` has
* been preallocated in advance to a public length if we hit this
* branch.
*
*/
return bn_num_bits_consttime(a);
}
if (BN_is_zero(a)) if (BN_is_zero(a))
return 0; return 0;
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
} }
@ -613,8 +658,11 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
return (ret); return (ret);
} }
typedef enum {big, little} endianess_t;
/* ignore negative */ /* ignore negative */
static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) static
int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess)
{ {
int n; int n;
size_t i, lasti, j, atop, mask; size_t i, lasti, j, atop, mask;
@ -646,10 +694,17 @@ static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
lasti = atop - 1; lasti = atop - 1;
atop = a->top * BN_BYTES; atop = a->top * BN_BYTES;
for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { if (endianess == big)
to += tolen; /* start from the end of the buffer */
for (i = 0, j = 0; j < (size_t)tolen; j++) {
unsigned char val;
l = a->d[i / BN_BYTES]; l = a->d[i / BN_BYTES];
mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
*--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
if (endianess == big)
*--to = val;
else
*to++ = val;
i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
} }
@ -660,21 +715,66 @@ int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{ {
if (tolen < 0) if (tolen < 0)
return -1; return -1;
return bn2binpad(a, to, tolen); return bn2binpad(a, to, tolen, big);
} }
int BN_bn2bin(const BIGNUM *a, unsigned char *to) int BN_bn2bin(const BIGNUM *a, unsigned char *to)
{ {
int n, i; return bn2binpad(a, to, -1, big);
BN_ULONG l; }
bn_check_top(a); BIGNUM *bn_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
n = i = BN_num_bytes(a); {
while (i--) { unsigned int i, m;
l = a->d[i / BN_BYTES]; unsigned int n;
*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; 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;
} }
return (n); 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;
}
int bn_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
{
if (tolen < 0)
return -1;
return bn2binpad(a, to, tolen, little);
} }
int BN_ucmp(const BIGNUM *a, const BIGNUM *b) int BN_ucmp(const BIGNUM *a, const BIGNUM *b)

View File

@ -19,3 +19,6 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
BIGNUM *bn_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
int bn_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);

View File

@ -4,7 +4,7 @@
* project. * project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved. * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -422,6 +422,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
unsigned char *ek = NULL; unsigned char *ek = NULL;
size_t eklen; size_t eklen;
int ret = 0; int ret = 0;
size_t fixlen = 0;
CMS_EncryptedContentInfo *ec; CMS_EncryptedContentInfo *ec;
ec = cms->d.envelopedData->encryptedContentInfo; ec = cms->d.envelopedData->encryptedContentInfo;
@ -430,6 +431,19 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
return 0; return 0;
} }
if (cms->d.envelopedData->encryptedContentInfo->havenocert
&& !cms->d.envelopedData->encryptedContentInfo->debug) {
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
if (ciph == NULL) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
return 0;
}
fixlen = EVP_CIPHER_key_length(ciph);
}
ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ktri->pctx) if (!ktri->pctx)
return 0; return 0;
@ -460,7 +474,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
ktri->encryptedKey->data, ktri->encryptedKey->data,
ktri->encryptedKey->length) <= 0) { ktri->encryptedKey->length) <= 0
|| eklen == 0
|| (fixlen != 0 && eklen != fixlen)) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
goto err; goto err;
} }

View File

@ -4,7 +4,7 @@
* project. * project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved. * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -172,6 +172,8 @@ struct CMS_EncryptedContentInfo_st {
size_t keylen; size_t keylen;
/* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
int debug; int debug;
/* Set to 1 if we have no cert and need extra safety measures for MMA */
int havenocert;
}; };
struct CMS_RecipientInfo_st { struct CMS_RecipientInfo_st {

View File

@ -4,7 +4,7 @@
* project. * project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved. * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -737,6 +737,10 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
cms->d.envelopedData->encryptedContentInfo->debug = 1; cms->d.envelopedData->encryptedContentInfo->debug = 1;
else else
cms->d.envelopedData->encryptedContentInfo->debug = 0; cms->d.envelopedData->encryptedContentInfo->debug = 0;
if (!cert)
cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
else
cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
if (!pk && !cert && !dcont && !out) if (!pk && !cert && !dcont && !out)
return 1; return 1;
if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))

View File

@ -6,7 +6,7 @@
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
* (Google). * (Google).
* ==================================================================== * ====================================================================
* Copyright (c) 2014 The OpenSSL Project. All rights reserved. * Copyright (c) 2014-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -185,11 +185,29 @@ static inline unsigned char constant_time_eq_int_8(int a, int b)
return constant_time_eq_8((unsigned)(a), (unsigned)(b)); return constant_time_eq_8((unsigned)(a), (unsigned)(b));
} }
/*
* Returns the value unmodified, but avoids optimizations.
* The barriers prevent the compiler from narrowing down the
* possible value range of the mask and ~mask in the select
* statements, which avoids the recognition of the select
* and turning it into a conditional load or branch.
*/
static inline unsigned int value_barrier(unsigned int a)
{
#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
unsigned int r;
__asm__("" : "=r"(r) : "0"(a));
#else
volatile unsigned int r = a;
#endif
return r;
}
static inline unsigned int constant_time_select(unsigned int mask, static inline unsigned int constant_time_select(unsigned int mask,
unsigned int a, unsigned int a,
unsigned int b) unsigned int b)
{ {
return (mask & a) | (~mask & b); return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
} }
static inline unsigned char constant_time_select_8(unsigned char mask, static inline unsigned char constant_time_select_8(unsigned char mask,

View File

@ -106,6 +106,8 @@ extern int OPENSSL_NONPIC_relocated;
char *ossl_safe_getenv(const char *); char *ossl_safe_getenv(const char *);
unsigned long OPENSSL_rdtsc(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project. * Written by Nils Larsch for the OpenSSL project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. * Copyright (c) 2000-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -695,10 +695,12 @@ ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
{ {
int ok = 0, tmp; int ok = 0, tmp;
EC_GROUP *ret = NULL; EC_GROUP *ret = NULL, *dup = NULL;
BIGNUM *p = NULL, *a = NULL, *b = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL;
EC_POINT *point = NULL; EC_POINT *point = NULL;
long field_bits; long field_bits;
int curve_name = NID_undef;
BN_CTX *ctx = NULL;
if (!params->fieldID || !params->fieldID->fieldType || if (!params->fieldID || !params->fieldID->fieldType ||
!params->fieldID->p.ptr) { !params->fieldID->p.ptr) {
@ -914,13 +916,75 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
goto err; goto err;
} }
/*
* Check if the explicit parameters group just created matches one of the
* built-in curves.
*
* We create a copy of the group just built, so that we can remove optional
* fields for the lookup: we do this to avoid the possibility that one of
* the optional parameters is used to force the library into using a less
* performant and less secure EC_METHOD instead of the specialized one.
* In any case, `seed` is not really used in any computation, while a
* cofactor different from the one in the built-in table is just
* mathematically wrong anyway and should not be used.
*/
if ((ctx = BN_CTX_new()) == NULL) {
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
goto err;
}
if ((dup = EC_GROUP_dup(ret)) == NULL
|| EC_GROUP_set_seed(dup, NULL, 0) != 1
|| !EC_GROUP_set_generator(dup, point, a, NULL)) {
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
goto err;
}
if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
/*
* The input explicit parameters successfully matched one of the
* built-in curves: often for built-in curves we have specialized
* methods with better performance and hardening.
*
* In this case we replace the `EC_GROUP` created through explicit
* parameters with one created from a named group.
*/
EC_GROUP *named_group = NULL;
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/*
* NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
* the same curve, we prefer the SECP nid when matching explicit
* parameters as that is associated with a specialized EC_METHOD.
*/
if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
curve_name = NID_secp224r1;
#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
goto err;
}
EC_GROUP_free(ret);
ret = named_group;
/*
* Set the flag so that EC_GROUPs created from explicit parameters are
* serialized using explicit parameters by default.
*
* 0x0 = OPENSSL_EC_EXPLICIT_CURVE
*/
EC_GROUP_set_asn1_flag(ret, 0x0);
}
ok = 1; ok = 1;
err:if (!ok) { err:
if (!ok) {
if (ret) if (ret)
EC_GROUP_clear_free(ret); EC_GROUP_free(ret);
ret = NULL; ret = NULL;
} }
if (dup)
EC_GROUP_free(dup);
if (p) if (p)
BN_free(p); BN_free(p);
@ -930,6 +994,8 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
BN_free(b); BN_free(b);
if (point) if (point)
EC_POINT_free(point); EC_POINT_free(point);
if (ctx)
BN_CTX_free(ctx);
return (ret); return (ret);
} }
@ -990,7 +1056,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
} }
if (a && *a) if (a && *a)
EC_GROUP_clear_free(*a); EC_GROUP_free(*a);
if (a) if (a)
*a = group; *a = group;
@ -1040,7 +1106,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
if (priv_key->parameters) { if (priv_key->parameters) {
if (ret->group) if (ret->group)
EC_GROUP_clear_free(ret->group); EC_GROUP_free(ret->group);
ret->group = ec_asn1_pkparameters2group(priv_key->parameters); ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
} }

View File

@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project. * Written by Nils Larsch for the OpenSSL project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -75,6 +75,8 @@
#include <openssl/obj_mac.h> #include <openssl/obj_mac.h>
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#include "bn_int.h"
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
# include <openssl/fips.h> # include <openssl/fips.h>
#endif #endif
@ -3246,3 +3248,115 @@ int EC_curve_nist2nid(const char *name)
} }
return NID_undef; return NID_undef;
} }
#define NUM_BN_FIELDS 6
/*
* Validates EC domain parameter data for known named curves.
* This can be used when a curve is loaded explicitly (without a curve
* name) or to validate that domain parameters have not been modified.
*
* Returns: The nid associated with the found named curve, or NID_undef
* if not found. If there was an error it returns -1.
*/
int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
{
int ret = -1, nid, len, field_type, param_len;
size_t i, seed_len;
const unsigned char *seed, *params_seed, *params;
unsigned char *param_bytes = NULL;
const EC_CURVE_DATA *data;
const EC_POINT *generator = NULL;
const EC_METHOD *meth;
const BIGNUM *cofactor = NULL;
/* An array of BIGNUMs for (p, a, b, x, y, order) */
BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
meth = EC_GROUP_method_of(group);
if (meth == NULL)
return -1;
/* Use the optional named curve nid as a search field */
nid = EC_GROUP_get_curve_name(group);
field_type = EC_METHOD_get_field_type(meth);
seed_len = EC_GROUP_get_seed_len(group);
seed = EC_GROUP_get0_seed(group);
cofactor = &group->cofactor;
BN_CTX_start(ctx);
/*
* The built-in curves contains data fields (p, a, b, x, y, order) that are
* all zero-padded to be the same size. The size of the padding is
* determined by either the number of bytes in the field modulus (p) or the
* EC group order, whichever is larger.
*/
param_len = BN_num_bytes(&group->order);
len = BN_num_bytes(&group->field);
if (len > param_len)
param_len = len;
/* Allocate space to store the padded data for (p, a, b, x, y, order) */
param_bytes = OPENSSL_malloc(param_len * NUM_BN_FIELDS);
if (param_bytes == NULL)
goto end;
/* Create the bignums */
for (i = 0; i < NUM_BN_FIELDS; ++i) {
if ((bn[i] = BN_CTX_get(ctx)) == NULL)
goto end;
}
/*
* Fill in the bn array with the same values as the internal curves
* i.e. the values are p, a, b, x, y, order.
*/
/* Get p, a & b */
if (!(ec_group_get_curve(group, bn[0], bn[1], bn[2], ctx)
&& ((generator = EC_GROUP_get0_generator(group)) != NULL)
/* Get x & y */
&& ec_point_get_affine_coordinates(group, generator, bn[3], bn[4], ctx)
/* Get order */
&& EC_GROUP_get_order(group, bn[5], ctx)))
goto end;
/*
* Convert the bignum array to bytes that are joined together to form
* a single buffer that contains data for all fields.
* (p, a, b, x, y, order) are all zero padded to be the same size.
*/
for (i = 0; i < NUM_BN_FIELDS; ++i) {
if (bn_bn2binpad(bn[i], &param_bytes[i*param_len], param_len) <= 0)
goto end;
}
for (i = 0; i < curve_list_length; i++) {
const ec_list_element curve = curve_list[i];
data = curve.data;
/* Get the raw order byte data */
params_seed = (const unsigned char *)(data + 1); /* skip header */
params = params_seed + data->seed_len;
/* Look for unique fields in the fixed curve data */
if (data->field_type == field_type
&& param_len == data->param_len
&& (nid <= 0 || nid == curve.nid)
/* check the optional cofactor (ignore if its zero) */
&& (BN_is_zero(cofactor)
|| BN_is_word(cofactor, (const BN_ULONG)curve.data->cofactor))
/* Check the optional seed (ignore if its not set) */
&& (data->seed_len == 0 || seed_len == 0
|| ((size_t)data->seed_len == seed_len
&& memcmp(params_seed, seed, seed_len) == 0))
/* Check that the groups params match the built-in curve params */
&& memcmp(param_bytes, params, param_len * NUM_BN_FIELDS)
== 0) {
ret = curve.nid;
goto end;
}
}
/* Gets here if the group was not found */
ret = NID_undef;
end:
OPENSSL_free(param_bytes);
BN_CTX_end(ctx);
return ret;
}

View File

@ -1,6 +1,6 @@
/* crypto/ec/ec_err.c */ /* crypto/ec/ec_err.c */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -310,6 +310,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
{ERR_REASON(EC_R_SLOT_FULL), "slot full"}, {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
{ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
{ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
{ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
{ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},

View File

@ -3,7 +3,7 @@
* Originally written by Bodo Moeller for the OpenSSL project. * Originally written by Bodo Moeller for the OpenSSL project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -565,3 +565,18 @@ EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx); const BIGNUM *b, BN_CTX *ctx);
EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid); EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid);
#endif #endif
int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
/*
* The next 2 functions are just internal wrappers around the omonimous
* functions with either the `_GFp` or the `_GF2m` suffix.
*
* They are meant to facilitate backporting of code from newer branches, where
* the public API includes a "field agnostic" version of these 2 functions.
*/
int ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *ctx);
int ec_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point, BIGNUM *x,
BIGNUM *y, BN_CTX *ctx);

View File

@ -294,6 +294,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
return meth->field_type; return meth->field_type;
} }
/*-
* Try computing cofactor from the generator order (n) and field cardinality (q).
* This works for all curves of cryptographic interest.
*
* Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
* h_min = (q + 1 - 2*sqrt(q))/n
* h_max = (q + 1 + 2*sqrt(q))/n
* h_max - h_min = 4*sqrt(q)/n
* So if n > 4*sqrt(q) holds, there is only one possible value for h:
* h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
*
* Otherwise, zero cofactor and return success.
*/
static int ec_guess_cofactor(EC_GROUP *group) {
int ret = 0;
BN_CTX *ctx = NULL;
BIGNUM *q = NULL;
/*-
* If the cofactor is too large, we cannot guess it.
* The RHS of below is a strict overestimate of lg(4 * sqrt(q))
*/
if (BN_num_bits(&group->order) <= (BN_num_bits(&group->field) + 1) / 2 + 3) {
/* default to 0 */
BN_zero(&group->cofactor);
/* return success */
return 1;
}
if ((ctx = BN_CTX_new()) == NULL)
return 0;
BN_CTX_start(ctx);
if ((q = BN_CTX_get(ctx)) == NULL)
goto err;
/* set q = 2**m for binary fields; q = p otherwise */
if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
BN_zero(q);
if (!BN_set_bit(q, BN_num_bits(&group->field) - 1))
goto err;
} else {
if (!BN_copy(q, &group->field))
goto err;
}
/* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
if (!BN_rshift1(&group->cofactor, &group->order) /* n/2 */
|| !BN_add(&group->cofactor, &group->cofactor, q) /* q + n/2 */
/* q + 1 + n/2 */
|| !BN_add(&group->cofactor, &group->cofactor, BN_value_one())
/* (q + 1 + n/2)/n */
|| !BN_div(&group->cofactor, NULL, &group->cofactor, &group->order, ctx))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return ret;
}
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor) const BIGNUM *order, const BIGNUM *cofactor)
{ {
@ -302,6 +363,33 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
return 0; return 0;
} }
/* require group->field >= 1 */
if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) {
ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
return 0;
}
/*-
* - require order >= 1
* - enforce upper bound due to Hasse thm: order can be no more than one bit
* longer than field cardinality
*/
if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
|| BN_num_bits(order) > BN_num_bits(&group->field) + 1) {
ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
return 0;
}
/*-
* Unfortunately the cofactor is an optional field in many standards.
* Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
* So accept cofactor == NULL or cofactor >= 0.
*/
if (cofactor != NULL && BN_is_negative(cofactor)) {
ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
return 0;
}
if (group->generator == NULL) { if (group->generator == NULL) {
group->generator = EC_POINT_new(group); group->generator = EC_POINT_new(group);
if (group->generator == NULL) if (group->generator == NULL)
@ -310,17 +398,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
if (!EC_POINT_copy(group->generator, generator)) if (!EC_POINT_copy(group->generator, generator))
return 0; return 0;
if (order != NULL) { if (!BN_copy(&group->order, order))
if (!BN_copy(&group->order, order)) return 0;
return 0;
} else
BN_zero(&group->order);
if (cofactor != NULL) { /* Either take the provided positive cofactor, or try to compute it */
if (cofactor != NULL && !BN_is_zero(cofactor)) {
if (!BN_copy(&group->cofactor, cofactor)) if (!BN_copy(&group->cofactor, cofactor))
return 0; return 0;
} else } else if (!ec_guess_cofactor(group)) {
BN_zero(&group->cofactor); BN_zero(&group->cofactor);
return 0;
}
/*- /*-
* Access to the `mont_data` field of an EC_GROUP struct should always be * Access to the `mont_data` field of an EC_GROUP struct should always be
@ -1169,3 +1257,60 @@ int ec_precompute_mont_data(EC_GROUP *group)
BN_CTX_free(ctx); BN_CTX_free(ctx);
return ret; return ret;
} }
/*
* This is just a wrapper around the public functions
* - EC_GROUP_get_curve_GF2m
* - EC_GROUP_get_curve_GFp
*
* It is meant to facilitate backporting of code from newer branches, where
* the public API includes a "field agnostic" version of it.
*/
int ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *ctx)
{
int field_nid;
field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
#ifndef OPENSSL_NO_EC2M
if (field_nid == NID_X9_62_characteristic_two_field) {
return EC_GROUP_get_curve_GF2m(group, p, a, b, ctx);
} else
#endif /* !def(OPENSSL_NO_EC2M) */
if (field_nid == NID_X9_62_prime_field) {
return EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
} else {
/* this should never happen */
return 0;
}
}
/*
* This is just a wrapper around the public functions
* - EC_POINT_get_affine_coordinates_GF2m
* - EC_POINT_get_affine_coordinates_GFp
*
* It is meant to facilitate backporting of code from newer branches, where
* the public API includes a "field agnostic" version of it.
*/
int ec_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point, BIGNUM *x,
BIGNUM *y, BN_CTX *ctx)
{
int field_nid;
field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
#ifndef OPENSSL_NO_EC2M
if (field_nid == NID_X9_62_characteristic_two_field) {
return EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx);
} else
#endif /* !def(OPENSSL_NO_EC2M) */
if (field_nid == NID_X9_62_prime_field) {
return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
} else {
/* this should never happen */
return 0;
}
}

View File

@ -37,6 +37,7 @@
# include <string.h> # include <string.h>
# include <openssl/err.h> # include <openssl/err.h>
# include "ec_lcl.h" # include "ec_lcl.h"
# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */ /* even with gcc, the typedef won't work for 32-bit platforms */
@ -334,34 +335,21 @@ static void felem_to_bin28(u8 out[28], const felem in)
} }
} }
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
static void flip_endian(u8 *out, const u8 *in, unsigned len)
{
unsigned i;
for (i = 0; i < len; ++i)
out[i] = in[len - 1 - i];
}
/* From OpenSSL BIGNUM to internal representation */ /* From OpenSSL BIGNUM to internal representation */
static int BN_to_felem(felem out, const BIGNUM *bn) static int BN_to_felem(felem out, const BIGNUM *bn)
{ {
felem_bytearray b_in;
felem_bytearray b_out; felem_bytearray b_out;
unsigned num_bytes; int num_bytes;
/* BN_bn2bin eats leading zeroes */
memset(b_out, 0, sizeof(b_out));
num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
if (BN_is_negative(bn)) { if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0; return 0;
} }
num_bytes = BN_bn2bin(bn, b_in); num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
flip_endian(b_out, b_in, num_bytes); if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin28_to_felem(out, b_out); bin28_to_felem(out, b_out);
return 1; return 1;
} }
@ -369,10 +357,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* From internal representation to OpenSSL BIGNUM */ /* From internal representation to OpenSSL BIGNUM */
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
{ {
felem_bytearray b_in, b_out; felem_bytearray b_out;
felem_to_bin28(b_in, in); felem_to_bin28(b_out, in);
flip_endian(b_out, b_in, sizeof(b_out)); return bn_lebin2bn(b_out, sizeof(b_out), out);
return BN_bin2bn(b_out, sizeof(b_out), out);
} }
/******************************************************************************/ /******************************************************************************/
@ -1426,8 +1413,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL; felem_bytearray *secrets = NULL;
felem(*pre_comp)[17][3] = NULL; felem(*pre_comp)[17][3] = NULL;
felem *tmp_felems = NULL; felem *tmp_felems = NULL;
felem_bytearray tmp; int num_bytes;
unsigned num_bytes;
int have_pre_comp = 0; int have_pre_comp = 0;
size_t num_points = num; size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out; felem x_in, y_in, z_in, x_out, y_out, z_out;
@ -1509,14 +1495,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray)); memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
for (i = 0; i < num_points; ++i) { for (i = 0; i < num_points; ++i) {
if (i == num) if (i == num) {
/* the generator */ /* the generator */
{
p = EC_GROUP_get0_generator(group); p = EC_GROUP_get0_generator(group);
p_scalar = scalar; p_scalar = scalar;
} else } else {
/* the i^th point */ /* the i^th point */
{
p = points[i]; p = points[i];
p_scalar = scalars[i]; p_scalar = scalars[i];
} }
@ -1532,10 +1516,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar,
} else secrets[i], sizeof(secrets[i]));
num_bytes = BN_bn2bin(p_scalar, tmp); } else {
flip_endian(secrets[i], tmp, num_bytes); num_bytes = bn_bn2lebinpad(p_scalar,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */ /* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) || if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) || (!BN_to_felem(y_out, &p->Y)) ||
@ -1578,20 +1568,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
} else } else {
num_bytes = BN_bn2bin(scalar, tmp); num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
flip_endian(g_secret, tmp, num_bytes); }
/* do the multiplication with generator precomputation */ /* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
g_secret, g_secret,
mixed, (const felem(*)[17][3])pre_comp, g_pre_comp); mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
} else } else {
/* do the multiplication without generator precomputation */ /* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
}
/* reduce the output to its unique minimal representation */ /* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out); felem_contract(x_in, x_out);
felem_contract(y_in, y_out); felem_contract(y_in, y_out);

View File

@ -38,6 +38,7 @@
# include <string.h> # include <string.h>
# include <openssl/err.h> # include <openssl/err.h>
# include "ec_lcl.h" # include "ec_lcl.h"
# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */ /* even with gcc, the typedef won't work for 32-bit platforms */
@ -144,34 +145,21 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
*((u64 *)&out[24]) = in[3]; *((u64 *)&out[24]) = in[3];
} }
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
static void flip_endian(u8 *out, const u8 *in, unsigned len)
{
unsigned i;
for (i = 0; i < len; ++i)
out[i] = in[len - 1 - i];
}
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ /* BN_to_felem converts an OpenSSL BIGNUM into an felem */
static int BN_to_felem(felem out, const BIGNUM *bn) static int BN_to_felem(felem out, const BIGNUM *bn)
{ {
felem_bytearray b_in;
felem_bytearray b_out; felem_bytearray b_out;
unsigned num_bytes; int num_bytes;
/* BN_bn2bin eats leading zeroes */
memset(b_out, 0, sizeof(b_out));
num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
if (BN_is_negative(bn)) { if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0; return 0;
} }
num_bytes = BN_bn2bin(bn, b_in); num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
flip_endian(b_out, b_in, num_bytes); if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin32_to_felem(out, b_out); bin32_to_felem(out, b_out);
return 1; return 1;
} }
@ -179,10 +167,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ /* felem_to_BN converts an felem into an OpenSSL BIGNUM */
static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
{ {
felem_bytearray b_in, b_out; felem_bytearray b_out;
smallfelem_to_bin32(b_in, in); smallfelem_to_bin32(b_out, in);
flip_endian(b_out, b_in, sizeof(b_out)); return bn_lebin2bn(b_out, sizeof(b_out), out);
return BN_bin2bn(b_out, sizeof(b_out), out);
} }
/*- /*-
@ -2014,8 +2001,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL; felem_bytearray *secrets = NULL;
smallfelem(*pre_comp)[17][3] = NULL; smallfelem(*pre_comp)[17][3] = NULL;
smallfelem *tmp_smallfelems = NULL; smallfelem *tmp_smallfelems = NULL;
felem_bytearray tmp; unsigned i;
unsigned i, num_bytes; int num_bytes;
int have_pre_comp = 0; int have_pre_comp = 0;
size_t num_points = num; size_t num_points = num;
smallfelem x_in, y_in, z_in; smallfelem x_in, y_in, z_in;
@ -2097,17 +2084,15 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray)); memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem)); memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
for (i = 0; i < num_points; ++i) { for (i = 0; i < num_points; ++i) {
if (i == num) if (i == num) {
/* /*
* we didn't have a valid precomputation, so we pick the * we didn't have a valid precomputation, so we pick the
* generator * generator
*/ */
{
p = EC_GROUP_get0_generator(group); p = EC_GROUP_get0_generator(group);
p_scalar = scalar; p_scalar = scalar;
} else } else {
/* the i^th point */ /* the i^th point */
{
p = points[i]; p = points[i];
p_scalar = scalars[i]; p_scalar = scalars[i];
} }
@ -2123,10 +2108,16 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar,
} else secrets[i], sizeof(secrets[i]));
num_bytes = BN_bn2bin(p_scalar, tmp); } else {
flip_endian(secrets[i], tmp, num_bytes); num_bytes = bn_bn2lebinpad(p_scalar,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */ /* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) || if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) || (!BN_to_felem(y_out, &p->Y)) ||
@ -2171,20 +2162,21 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
} else } else {
num_bytes = BN_bn2bin(scalar, tmp); num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
flip_endian(g_secret, tmp, num_bytes); }
/* do the multiplication with generator precomputation */ /* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
g_secret, g_secret,
mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp); mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
} else } else {
/* do the multiplication without generator precomputation */ /* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL); NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
}
/* reduce the output to its unique minimal representation */ /* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out); felem_contract(x_in, x_out);
felem_contract(y_in, y_out); felem_contract(y_in, y_out);

View File

@ -38,6 +38,7 @@
# include <string.h> # include <string.h>
# include <openssl/err.h> # include <openssl/err.h>
# include "ec_lcl.h" # include "ec_lcl.h"
# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */ /* even with gcc, the typedef won't work for 32-bit platforms */
@ -168,34 +169,21 @@ static void felem_to_bin66(u8 out[66], const felem in)
(*((limb *) & out[58])) = in[8]; (*((limb *) & out[58])) = in[8];
} }
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
static void flip_endian(u8 *out, const u8 *in, unsigned len)
{
unsigned i;
for (i = 0; i < len; ++i)
out[i] = in[len - 1 - i];
}
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ /* BN_to_felem converts an OpenSSL BIGNUM into an felem */
static int BN_to_felem(felem out, const BIGNUM *bn) static int BN_to_felem(felem out, const BIGNUM *bn)
{ {
felem_bytearray b_in;
felem_bytearray b_out; felem_bytearray b_out;
unsigned num_bytes; int num_bytes;
/* BN_bn2bin eats leading zeroes */
memset(b_out, 0, sizeof(b_out));
num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
if (BN_is_negative(bn)) { if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0; return 0;
} }
num_bytes = BN_bn2bin(bn, b_in); num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
flip_endian(b_out, b_in, num_bytes); if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin66_to_felem(out, b_out); bin66_to_felem(out, b_out);
return 1; return 1;
} }
@ -203,10 +191,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ /* felem_to_BN converts an felem into an OpenSSL BIGNUM */
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
{ {
felem_bytearray b_in, b_out; felem_bytearray b_out;
felem_to_bin66(b_in, in); felem_to_bin66(b_out, in);
flip_endian(b_out, b_in, sizeof(b_out)); return bn_lebin2bn(b_out, sizeof(b_out), out);
return BN_bin2bn(b_out, sizeof(b_out), out);
} }
/*- /*-
@ -1826,8 +1813,8 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL; felem_bytearray *secrets = NULL;
felem(*pre_comp)[17][3] = NULL; felem(*pre_comp)[17][3] = NULL;
felem *tmp_felems = NULL; felem *tmp_felems = NULL;
felem_bytearray tmp; unsigned i;
unsigned i, num_bytes; int num_bytes;
int have_pre_comp = 0; int have_pre_comp = 0;
size_t num_points = num; size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out; felem x_in, y_in, z_in, x_out, y_out, z_out;
@ -1909,17 +1896,15 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray)); memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
for (i = 0; i < num_points; ++i) { for (i = 0; i < num_points; ++i) {
if (i == num) if (i == num) {
/* /*
* we didn't have a valid precomputation, so we pick the * we didn't have a valid precomputation, so we pick the
* generator * generator
*/ */
{
p = EC_GROUP_get0_generator(group); p = EC_GROUP_get0_generator(group);
p_scalar = scalar; p_scalar = scalar;
} else } else {
/* the i^th point */ /* the i^th point */
{
p = points[i]; p = points[i];
p_scalar = scalars[i]; p_scalar = scalars[i];
} }
@ -1935,10 +1920,16 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar,
} else secrets[i], sizeof(secrets[i]));
num_bytes = BN_bn2bin(p_scalar, tmp); } else {
flip_endian(secrets[i], tmp, num_bytes); num_bytes = bn_bn2lebinpad(p_scalar,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */ /* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) || if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) || (!BN_to_felem(y_out, &p->Y)) ||
@ -1981,21 +1972,22 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
goto err; goto err;
} }
num_bytes = BN_bn2bin(tmp_scalar, tmp); num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
} else } else {
num_bytes = BN_bn2bin(scalar, tmp); num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
flip_endian(g_secret, tmp, num_bytes); }
/* do the multiplication with generator precomputation */ /* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
g_secret, g_secret,
mixed, (const felem(*)[17][3])pre_comp, mixed, (const felem(*)[17][3])pre_comp,
(const felem(*)[3])g_pre_comp); (const felem(*)[3])g_pre_comp);
} else } else {
/* do the multiplication without generator precomputation */ /* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out, batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points, (const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
}
/* reduce the output to its unique minimal representation */ /* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out); felem_contract(x_in, x_out);
felem_contract(y_in, y_out); felem_contract(y_in, y_out);

View File

@ -3,7 +3,7 @@
* 2005. * 2005.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. * Copyright (c) 2005-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -327,6 +327,8 @@ static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
} else { } else {
if (!read_lebn(&p, 20, &dsa->priv_key)) if (!read_lebn(&p, 20, &dsa->priv_key))
goto memerr; goto memerr;
/* Set constant time flag before public key calculation */
BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME);
/* Calculate public key */ /* Calculate public key */
if (!(dsa->pub_key = BN_new())) if (!(dsa->pub_key = BN_new()))
goto memerr; goto memerr;

View File

@ -191,7 +191,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
} }
static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
size_t fixlen)
{ {
EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *pctx = NULL;
unsigned char *ek = NULL; unsigned char *ek = NULL;
@ -224,7 +225,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
} }
if (EVP_PKEY_decrypt(pctx, ek, &eklen, if (EVP_PKEY_decrypt(pctx, ek, &eklen,
ri->enc_key->data, ri->enc_key->length) <= 0) { ri->enc_key->data, ri->enc_key->length) <= 0
|| eklen == 0
|| (fixlen != 0 && eklen != fixlen)) {
ret = 0; ret = 0;
PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
goto err; goto err;
@ -571,13 +574,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
ri = sk_PKCS7_RECIP_INFO_value(rsk, i); ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
EVP_CIPHER_key_length(evp_cipher)) < 0)
goto err; goto err;
ERR_clear_error(); ERR_clear_error();
} }
} else { } else {
/* Only exit on fatal errors, not decrypt failure */ /* Only exit on fatal errors, not decrypt failure */
if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
goto err; goto err;
ERR_clear_error(); ERR_clear_error();
} }

View File

@ -1,6 +1,6 @@
/* crypto/rsa/rsa_chk.c */ /* crypto/rsa/rsa_chk.c */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -63,6 +63,10 @@ int RSA_check_key(const RSA *key)
return 0; return 0;
} }
/* Set consant-time flag on private parameters */
BN_set_flags(key->p, BN_FLG_CONSTTIME);
BN_set_flags(key->q, BN_FLG_CONSTTIME);
BN_set_flags(key->d, BN_FLG_CONSTTIME);
i = BN_new(); i = BN_new();
j = BN_new(); j = BN_new();
k = BN_new(); k = BN_new();
@ -141,6 +145,10 @@ int RSA_check_key(const RSA *key)
} }
if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
/* Set consant-time flag on CRT parameters */
BN_set_flags(key->dmp1, BN_FLG_CONSTTIME);
BN_set_flags(key->dmq1, BN_FLG_CONSTTIME);
BN_set_flags(key->iqmp, BN_FLG_CONSTTIME);
/* dmp1 = d mod (p-1)? */ /* dmp1 = d mod (p-1)? */
if (!BN_sub(i, key->p, BN_value_one())) { if (!BN_sub(i, key->p, BN_value_one())) {
ret = -1; ret = -1;

View File

@ -490,6 +490,8 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
STACK_OF(X509) *ret; STACK_OF(X509) *ret;
int i; int i;
ret = sk_X509_dup(chain); ret = sk_X509_dup(chain);
if (ret == NULL)
return NULL;
for (i = 0; i < sk_X509_num(ret); i++) { for (i = 0; i < sk_X509_num(ret); i++) {
X509 *x = sk_X509_value(ret, i); X509 *x = sk_X509_value(ret, i);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);

View File

@ -4,7 +4,7 @@
* project. * project.
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -205,15 +205,18 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
break; break;
case GEN_EMAIL: case GEN_EMAIL:
BIO_printf(out, "email:%s", gen->d.ia5->data); BIO_printf(out, "email:");
ASN1_STRING_print(out, gen->d.ia5);
break; break;
case GEN_DNS: case GEN_DNS:
BIO_printf(out, "DNS:%s", gen->d.ia5->data); BIO_printf(out, "DNS:");
ASN1_STRING_print(out, gen->d.ia5);
break; break;
case GEN_URI: case GEN_URI:
BIO_printf(out, "URI:%s", gen->d.ia5->data); BIO_printf(out, "URI:");
ASN1_STRING_print(out, gen->d.ia5);
break; break;
case GEN_DIRNAME: case GEN_DIRNAME:

View File

@ -7,7 +7,7 @@
* \author Originally written by Bodo Moeller for the OpenSSL project * \author Originally written by Bodo Moeller for the OpenSSL project
*/ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -1073,6 +1073,7 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
* The following lines are auto generated by the script mkerr.pl. Any changes * The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run. * made after this point may be overwritten when the script is next run.
*/ */
void ERR_load_EC_strings(void); void ERR_load_EC_strings(void);
/* Error codes for the EC functions. */ /* Error codes for the EC functions. */
@ -1270,13 +1271,14 @@ void ERR_load_EC_strings(void);
# define EC_R_SLOT_FULL 108 # define EC_R_SLOT_FULL 108
# define EC_R_UNDEFINED_GENERATOR 113 # define EC_R_UNDEFINED_GENERATOR 113
# define EC_R_UNDEFINED_ORDER 128 # define EC_R_UNDEFINED_ORDER 128
# define EC_R_UNKNOWN_COFACTOR 152
# define EC_R_UNKNOWN_GROUP 129 # define EC_R_UNKNOWN_GROUP 129
# define EC_R_UNKNOWN_ORDER 114 # define EC_R_UNKNOWN_ORDER 114
# define EC_R_UNSUPPORTED_FIELD 131 # define EC_R_UNSUPPORTED_FIELD 131
# define EC_R_WRONG_CURVE_PARAMETERS 145 # define EC_R_WRONG_CURVE_PARAMETERS 145
# define EC_R_WRONG_ORDER 130 # define EC_R_WRONG_ORDER 130
#ifdef __cplusplus # ifdef __cplusplus
} }
#endif # endif
#endif #endif

View File

@ -255,7 +255,7 @@ extern "C" {
even newer MIPS CPU's, but at the moment one size fits all for even newer MIPS CPU's, but at the moment one size fits all for
optimization options. Older Sparc's work better with only UNROLL, but optimization options. Older Sparc's work better with only UNROLL, but
there's no way to tell at compile time what it is you're running on */ there's no way to tell at compile time what it is you're running on */
#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */
# define DES_PTR # define DES_PTR
# define DES_RISC1 # define DES_RISC1

View File

@ -30,11 +30,11 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta) * major minor fix final patch/beta)
*/ */
# define OPENSSL_VERSION_NUMBER 0x1000213fL # define OPENSSL_VERSION_NUMBER 0x1000214fL
# ifdef OPENSSL_FIPS # ifdef OPENSSL_FIPS
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2s-fips 28 May 2019" # define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2t-fips 10 Sep 2019"
# else # else
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2s 28 May 2019" # define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2t 10 Sep 2019"
# endif # endif
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@ -0,0 +1,35 @@
diff --git a/thirdparty/openssl/openssl/opensslconf.h b/thirdparty/openssl/openssl/opensslconf.h
index 619e5ca48b..0edbf7b1c5 100644
--- a/thirdparty/openssl/openssl/opensslconf.h
+++ b/thirdparty/openssl/openssl/opensslconf.h
@@ -123,7 +123,11 @@ extern "C" {
# endif
#endif
-#define OPENSSL_CPUID_OBJ
+// -- GODOT start --
+// Added in 1.0.2s and we didn't define it up to now,
+// so keeping it as previously to ensure compatibility.
+//#define OPENSSL_CPUID_OBJ
+// -- GODOT end --
/* crypto/opensslconf.h.in */
@@ -190,10 +194,15 @@ extern "C" {
/* Should we define BN_DIV2W here? */
/* Only one for the following should be defined */
-#define SIXTY_FOUR_BIT_LONG
+// -- GODOT start --
+// Default changed in 1.0.2s, we keep previous value to ensure compatibility.
+//#define SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT_LONG
#undef SIXTY_FOUR_BIT
-#undef THIRTY_TWO_BIT
+//#undef THIRTY_TWO_BIT
+#define THIRTY_TWO_BIT
#endif
+// -- GODOT end --
#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
#define CONFIG_HEADER_RC4_LOCL_H