Update - OpenSSL 1.1.1-pre7-dev
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
@@ -1633,7 +1633,7 @@ ___
|
||||
$code.=<<___;
|
||||
.Ladd_done:
|
||||
add sp,sp,#32*18+16+16 @ +16 means "skip even over saved r0-r3"
|
||||
#if __ARM_ARCH__>=5 || defined(__thumb__)
|
||||
#if __ARM_ARCH__>=5 || !defined(__thumb__)
|
||||
ldmia sp!,{r4-r12,pc}
|
||||
#else
|
||||
ldmia sp!,{r4-r12,lr}
|
||||
|
||||
@@ -2,7 +2,7 @@ LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \
|
||||
ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
|
||||
ec2_smpl.c ec_ameth.c ec_pmeth.c eck_prn.c \
|
||||
ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
|
||||
ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define INLINE_UNUSED __inline__ __attribute__((__unused__,__always_inline__))
|
||||
# define RESTRICT __restrict__
|
||||
# define ALIGNED __attribute__((__aligned__(32)))
|
||||
# define ALIGNED __attribute__((__aligned__(16)))
|
||||
# else
|
||||
# define INLINE_UNUSED ossl_inline
|
||||
# define RESTRICT
|
||||
|
||||
@@ -1,404 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
/*-
|
||||
* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
|
||||
* coordinates.
|
||||
* Uses algorithm Mdouble in appendix of
|
||||
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
|
||||
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
|
||||
* modified to not require precomputation of c=b^{2^{m-1}}.
|
||||
*/
|
||||
static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t1;
|
||||
int ret = 0;
|
||||
|
||||
/* Since Mdouble is static we can guarantee that ctx != NULL. */
|
||||
BN_CTX_start(ctx);
|
||||
t1 = BN_CTX_get(ctx);
|
||||
if (t1 == NULL)
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_sqr(group, x, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, t1, z, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, z, x, t1, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, x, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, t1, t1, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, t1, group->b, t1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x, x, t1))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
|
||||
* projective coordinates.
|
||||
* Uses algorithm Madd in appendix of
|
||||
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
|
||||
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
|
||||
*/
|
||||
static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1,
|
||||
BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t1, *t2;
|
||||
int ret = 0;
|
||||
|
||||
/* Since Madd is static we can guarantee that ctx != NULL. */
|
||||
BN_CTX_start(ctx);
|
||||
t1 = BN_CTX_get(ctx);
|
||||
t2 = BN_CTX_get(ctx);
|
||||
if (t2 == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_copy(t1, x))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, x1, x1, z2, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, z1, z1, x2, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, t2, x1, z1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(z1, z1, x1))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, z1, z1, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, x1, z1, t1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x1, x1, t2))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
|
||||
* using Montgomery point multiplication algorithm Mxy() in appendix of
|
||||
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
|
||||
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
|
||||
* Returns:
|
||||
* 0 on error
|
||||
* 1 if return value should be the point at infinity
|
||||
* 2 otherwise
|
||||
*/
|
||||
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y,
|
||||
BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t3, *t4, *t5;
|
||||
int ret = 0;
|
||||
|
||||
if (BN_is_zero(z1)) {
|
||||
BN_zero(x2);
|
||||
BN_zero(z2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (BN_is_zero(z2)) {
|
||||
if (!BN_copy(x2, x))
|
||||
return 0;
|
||||
if (!BN_GF2m_add(z2, x, y))
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Since Mxy is static we can guarantee that ctx != NULL. */
|
||||
BN_CTX_start(ctx);
|
||||
t3 = BN_CTX_get(ctx);
|
||||
t4 = BN_CTX_get(ctx);
|
||||
t5 = BN_CTX_get(ctx);
|
||||
if (t5 == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_one(t5))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_mul(group, t3, z1, z2, ctx))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_mul(group, z1, z1, x, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(z1, z1, x1))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, z2, z2, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, x1, z2, x1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(z2, z2, x2))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_mul(group, z2, z2, z1, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, t4, x, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(t4, t4, y))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, t4, t4, t3, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(t4, t4, z2))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_mul(group, t3, t3, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_div(group, t3, t5, t3, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, t4, t3, t4, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, x2, x1, t3, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(z2, x2, x))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_mul(group, z2, z2, t4, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(z2, z2, y))
|
||||
goto err;
|
||||
|
||||
ret = 2;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Computes scalar*point and stores the result in r.
|
||||
* point can not equal r.
|
||||
* Uses a modified algorithm 2P of
|
||||
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
|
||||
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
|
||||
*
|
||||
* To protect against side-channel attack the function uses constant time swap,
|
||||
* avoiding conditional branches.
|
||||
*/
|
||||
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
|
||||
EC_POINT *r,
|
||||
const BIGNUM *scalar,
|
||||
const EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *x1, *x2, *z1, *z2;
|
||||
int ret = 0, i, group_top;
|
||||
BN_ULONG mask, word;
|
||||
|
||||
if (r == point) {
|
||||
ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if result should be point at infinity */
|
||||
if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
|
||||
EC_POINT_is_at_infinity(group, point)) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
/* only support affine coordinates */
|
||||
if (!point->Z_is_one)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Since point_multiply is static we can guarantee that ctx != NULL.
|
||||
*/
|
||||
BN_CTX_start(ctx);
|
||||
x1 = BN_CTX_get(ctx);
|
||||
z1 = BN_CTX_get(ctx);
|
||||
if (z1 == NULL)
|
||||
goto err;
|
||||
|
||||
x2 = r->X;
|
||||
z2 = r->Y;
|
||||
|
||||
group_top = bn_get_top(group->field);
|
||||
if (bn_wexpand(x1, group_top) == NULL
|
||||
|| bn_wexpand(z1, group_top) == NULL
|
||||
|| bn_wexpand(x2, group_top) == NULL
|
||||
|| bn_wexpand(z2, group_top) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_GF2m_mod_arr(x1, point->X, group->poly))
|
||||
goto err; /* x1 = x */
|
||||
if (!BN_one(z1))
|
||||
goto err; /* z1 = 1 */
|
||||
if (!group->meth->field_sqr(group, z2, x1, ctx))
|
||||
goto err; /* z2 = x1^2 = x^2 */
|
||||
if (!group->meth->field_sqr(group, x2, z2, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, group->b))
|
||||
goto err; /* x2 = x^4 + b */
|
||||
|
||||
/* find top most bit and go one past it */
|
||||
i = bn_get_top(scalar) - 1;
|
||||
mask = BN_TBIT;
|
||||
word = bn_get_words(scalar)[i];
|
||||
while (!(word & mask))
|
||||
mask >>= 1;
|
||||
mask >>= 1;
|
||||
/* if top most bit was at word break, go to next word */
|
||||
if (!mask) {
|
||||
i--;
|
||||
mask = BN_TBIT;
|
||||
}
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
word = bn_get_words(scalar)[i];
|
||||
while (mask) {
|
||||
BN_consttime_swap(word & mask, x1, x2, group_top);
|
||||
BN_consttime_swap(word & mask, z1, z2, group_top);
|
||||
if (!gf2m_Madd(group, point->X, x2, z2, x1, z1, ctx))
|
||||
goto err;
|
||||
if (!gf2m_Mdouble(group, x1, z1, ctx))
|
||||
goto err;
|
||||
BN_consttime_swap(word & mask, x1, x2, group_top);
|
||||
BN_consttime_swap(word & mask, z1, z2, group_top);
|
||||
mask >>= 1;
|
||||
}
|
||||
mask = BN_TBIT;
|
||||
}
|
||||
|
||||
/* convert out of "projective" coordinates */
|
||||
i = gf2m_Mxy(group, point->X, point->Y, x1, z1, x2, z2, ctx);
|
||||
if (i == 0)
|
||||
goto err;
|
||||
else if (i == 1) {
|
||||
if (!EC_POINT_set_to_infinity(group, r))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_one(r->Z))
|
||||
goto err;
|
||||
r->Z_is_one = 1;
|
||||
}
|
||||
|
||||
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
|
||||
BN_set_negative(r->X, 0);
|
||||
BN_set_negative(r->Y, 0);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Computes the sum
|
||||
* scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
|
||||
* gracefully ignoring NULL scalar values.
|
||||
*/
|
||||
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
EC_POINT *p = NULL;
|
||||
EC_POINT *acc = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implementation is more efficient than the wNAF implementation for
|
||||
* 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more
|
||||
* points, or if we can perform a fast multiplication based on
|
||||
* precomputation.
|
||||
*/
|
||||
if ((scalar && (num > 1)) || (num > 2)
|
||||
|| (num == 0 && EC_GROUP_have_precompute_mult(group))) {
|
||||
ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((p = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
if ((acc = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_set_to_infinity(group, acc))
|
||||
goto err;
|
||||
|
||||
if (scalar) {
|
||||
if (!ec_GF2m_montgomery_point_multiply
|
||||
(group, p, scalar, group->generator, ctx))
|
||||
goto err;
|
||||
if (BN_is_negative(scalar))
|
||||
if (!group->meth->invert(group, p, ctx))
|
||||
goto err;
|
||||
if (!group->meth->add(group, acc, acc, p, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_GF2m_montgomery_point_multiply
|
||||
(group, p, scalars[i], points[i], ctx))
|
||||
goto err;
|
||||
if (BN_is_negative(scalars[i]))
|
||||
if (!group->meth->invert(group, p, ctx))
|
||||
goto err;
|
||||
if (!group->meth->add(group, acc, acc, p, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_copy(r, acc))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(p);
|
||||
EC_POINT_free(acc);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Precomputation for point multiplication: fall back to wNAF methods because
|
||||
* ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate
|
||||
*/
|
||||
|
||||
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
return ec_wNAF_precompute_mult(group, ctx);
|
||||
}
|
||||
|
||||
int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
return ec_wNAF_have_precompute_mult(group);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -47,14 +47,9 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
ec_GF2m_simple_cmp,
|
||||
ec_GF2m_simple_make_affine,
|
||||
ec_GF2m_simple_points_make_affine,
|
||||
|
||||
/*
|
||||
* the following three method functions are defined in ec2_mult.c
|
||||
*/
|
||||
ec_GF2m_simple_mul,
|
||||
ec_GF2m_precompute_mult,
|
||||
ec_GF2m_have_precompute_mult,
|
||||
|
||||
0 /* mul */,
|
||||
0 /* precompute_mul */,
|
||||
0 /* have_precompute_mul */,
|
||||
ec_GF2m_simple_field_mul,
|
||||
ec_GF2m_simple_field_sqr,
|
||||
ec_GF2m_simple_field_div,
|
||||
|
||||
+44
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -2751,6 +2751,45 @@ static const struct {
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
static const struct {
|
||||
EC_CURVE_DATA h;
|
||||
unsigned char data[0 + 32 * 6];
|
||||
} _EC_sm2p256v1 = {
|
||||
{
|
||||
NID_X9_62_prime_field, 0, 32, 1
|
||||
},
|
||||
{
|
||||
/* no seed */
|
||||
|
||||
/* p */
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
/* a */
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
||||
/* b */
|
||||
0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b,
|
||||
0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92,
|
||||
0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93,
|
||||
/* x */
|
||||
0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46,
|
||||
0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1,
|
||||
0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7,
|
||||
/* y */
|
||||
0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3,
|
||||
0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40,
|
||||
0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0,
|
||||
/* order */
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b,
|
||||
0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23,
|
||||
}
|
||||
};
|
||||
#endif /* OPENSSL_NO_SM2 */
|
||||
|
||||
typedef struct _ec_list_element_st {
|
||||
int nid;
|
||||
const EC_CURVE_DATA *data;
|
||||
@@ -2960,6 +2999,10 @@ static const ec_list_element curve_list[] = {
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{NID_sm2, &_EC_sm2p256v1.h, 0,
|
||||
"SM2 curve over a 256 bit prime field"},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define curve_list_length OSSL_NELEM(curve_list)
|
||||
|
||||
@@ -166,6 +166,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
"EC_GROUP_set_curve_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_GENERATOR, 0),
|
||||
"EC_GROUP_set_generator"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_SEED, 0), "EC_GROUP_set_seed"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_CHECK_KEY, 0), "EC_KEY_check_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_COPY, 0), "EC_KEY_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_GENERATE_KEY, 0), "EC_KEY_generate_key"},
|
||||
@@ -174,6 +175,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_OCT2PRIV, 0), "EC_KEY_oct2priv"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT, 0), "EC_KEY_print"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT_FP, 0), "EC_KEY_print_fp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2BUF, 0), "EC_KEY_priv2buf"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2OCT, 0), "EC_KEY_priv2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 0),
|
||||
"EC_KEY_set_public_key_affine_coordinates"},
|
||||
@@ -188,6 +190,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0),
|
||||
"EC_POINTs_make_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_COPY, 0), "EC_POINT_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_DBL, 0), "EC_POINT_dbl"},
|
||||
@@ -206,6 +209,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
"EC_POINT_make_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_NEW, 0), "EC_POINT_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_OCT2POINT, 0), "EC_POINT_oct2point"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2BUF, 0), "EC_POINT_point2buf"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2OCT, 0), "EC_POINT_point2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_set_affine_coordinates_GF2m"},
|
||||
@@ -246,10 +250,14 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
"pkey_ecd_digestsign25519"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0),
|
||||
"pkey_ecd_digestsign448"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_SIGN25519, 0), "pkey_ecd_sign25519"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_SIGN448, 0), "pkey_ecd_sign448"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_DERIVE, 0), "pkey_ec_derive"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_INIT, 0), "pkey_ec_init"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KDF_DERIVE, 0), "pkey_ec_kdf_derive"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"},
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -613,12 +613,14 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
|
||||
len = EC_KEY_priv2oct(eckey, NULL, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
buf = OPENSSL_malloc(len);
|
||||
if (buf == NULL)
|
||||
if ((buf = OPENSSL_malloc(len)) == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
len = EC_KEY_priv2oct(eckey, buf, len);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
|
||||
+17
-8
@@ -120,6 +120,23 @@ struct ec_method_st {
|
||||
* EC_POINT_have_precompute_mult (default implementations are used if the
|
||||
* 'mul' pointer is 0):
|
||||
*/
|
||||
/*-
|
||||
* mul() calculates the value
|
||||
*
|
||||
* r := generator * scalar
|
||||
* + points[0] * scalars[0]
|
||||
* + ...
|
||||
* + points[num-1] * scalars[num-1].
|
||||
*
|
||||
* For a fixed point multiplication (scalar != NULL, num == 0)
|
||||
* or a variable point multiplication (scalar == NULL, num == 1),
|
||||
* mul() must use a constant time algorithm: in both cases callers
|
||||
* should provide an input scalar (either scalar or scalars[0])
|
||||
* in the range [0, ec_group_order); for robustness, implementers
|
||||
* should handle the case when the scalar has not been reduced, but
|
||||
* may treat it as an unusual input, without any constant-timeness
|
||||
* guarantee.
|
||||
*/
|
||||
int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
@@ -426,14 +443,6 @@ int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
|
||||
/* method functions in ec2_mult.c */
|
||||
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
/* method functions in ecp_nistp224.c */
|
||||
int ec_GFp_nistp224_group_init(EC_GROUP *group);
|
||||
|
||||
+7
-4
@@ -213,9 +213,10 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
|
||||
if (src->seed) {
|
||||
OPENSSL_free(dest->seed);
|
||||
dest->seed = OPENSSL_malloc(src->seed_len);
|
||||
if (dest->seed == NULL)
|
||||
if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_COPY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!memcpy(dest->seed, src->seed, src->seed_len))
|
||||
return 0;
|
||||
dest->seed_len = src->seed_len;
|
||||
@@ -393,8 +394,10 @@ size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
|
||||
if (!len || !p)
|
||||
return 1;
|
||||
|
||||
if ((group->seed = OPENSSL_malloc(len)) == NULL)
|
||||
if ((group->seed = OPENSSL_malloc(len)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_SET_SEED, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(group->seed, p, len);
|
||||
group->seed_len = len;
|
||||
|
||||
@@ -557,7 +560,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
|
||||
ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (group->meth->point_init == 0) {
|
||||
if (group->meth->point_init == NULL) {
|
||||
ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+244
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -101,6 +101,223 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
|
||||
OPENSSL_free(pre);
|
||||
}
|
||||
|
||||
#define EC_POINT_BN_set_flags(P, flags) do { \
|
||||
BN_set_flags((P)->X, (flags)); \
|
||||
BN_set_flags((P)->Y, (flags)); \
|
||||
BN_set_flags((P)->Z, (flags)); \
|
||||
} while(0)
|
||||
|
||||
/*-
|
||||
* This functions computes (in constant time) a point multiplication over the
|
||||
* EC group.
|
||||
*
|
||||
* At a high level, it is Montgomery ladder with conditional swaps.
|
||||
*
|
||||
* It performs either a fixed point multiplication
|
||||
* (scalar * generator)
|
||||
* when point is NULL, or a variable point multiplication
|
||||
* (scalar * point)
|
||||
* when point is not NULL.
|
||||
*
|
||||
* scalar should be in the range [0,n) otherwise all constant time bets are off.
|
||||
*
|
||||
* NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
|
||||
* which of course are not constant time themselves.
|
||||
*
|
||||
* The product is stored in r.
|
||||
*
|
||||
* Returns 1 on success, 0 otherwise.
|
||||
*/
|
||||
static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, const EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int i, order_bits, group_top, kbit, pbit, Z_is_one;
|
||||
EC_POINT *s = NULL;
|
||||
BIGNUM *k = NULL;
|
||||
BIGNUM *lambda = NULL;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
order_bits = BN_num_bits(group->order);
|
||||
|
||||
s = EC_POINT_new(group);
|
||||
if (s == NULL)
|
||||
goto err;
|
||||
|
||||
if (point == NULL) {
|
||||
if (!EC_POINT_copy(s, group->generator))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_copy(s, point))
|
||||
goto err;
|
||||
}
|
||||
|
||||
EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
|
||||
|
||||
lambda = BN_CTX_get(ctx);
|
||||
k = BN_CTX_get(ctx);
|
||||
if (k == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Group orders are often on a word boundary.
|
||||
* So when we pad the scalar, some timing diff might
|
||||
* pop if it needs to be expanded due to carries.
|
||||
* So expand ahead of time.
|
||||
*/
|
||||
group_top = bn_get_top(group->order);
|
||||
if ((bn_wexpand(k, group_top + 1) == NULL)
|
||||
|| (bn_wexpand(lambda, group_top + 1) == NULL))
|
||||
goto err;
|
||||
|
||||
if (!BN_copy(k, scalar))
|
||||
goto err;
|
||||
|
||||
BN_set_flags(k, BN_FLG_CONSTTIME);
|
||||
|
||||
if ((BN_num_bits(k) > order_bits) || (BN_is_negative(k))) {
|
||||
/*-
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(k, k, group->order, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_add(lambda, k, group->order))
|
||||
goto err;
|
||||
BN_set_flags(lambda, BN_FLG_CONSTTIME);
|
||||
if (!BN_add(k, lambda, group->order))
|
||||
goto err;
|
||||
/*
|
||||
* lambda := scalar + order
|
||||
* k := scalar + 2*order
|
||||
*/
|
||||
kbit = BN_is_bit_set(lambda, order_bits);
|
||||
BN_consttime_swap(kbit, k, lambda, group_top + 1);
|
||||
|
||||
group_top = bn_get_top(group->field);
|
||||
if ((bn_wexpand(s->X, group_top) == NULL)
|
||||
|| (bn_wexpand(s->Y, group_top) == NULL)
|
||||
|| (bn_wexpand(s->Z, group_top) == NULL)
|
||||
|| (bn_wexpand(r->X, group_top) == NULL)
|
||||
|| (bn_wexpand(r->Y, group_top) == NULL)
|
||||
|| (bn_wexpand(r->Z, group_top) == NULL))
|
||||
goto err;
|
||||
|
||||
/* top bit is a 1, in a fixed pos */
|
||||
if (!EC_POINT_copy(r, s))
|
||||
goto err;
|
||||
|
||||
EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
|
||||
|
||||
if (!EC_POINT_dbl(group, s, s, ctx))
|
||||
goto err;
|
||||
|
||||
pbit = 0;
|
||||
|
||||
#define EC_POINT_CSWAP(c, a, b, w, t) do { \
|
||||
BN_consttime_swap(c, (a)->X, (b)->X, w); \
|
||||
BN_consttime_swap(c, (a)->Y, (b)->Y, w); \
|
||||
BN_consttime_swap(c, (a)->Z, (b)->Z, w); \
|
||||
t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
|
||||
(a)->Z_is_one ^= (t); \
|
||||
(b)->Z_is_one ^= (t); \
|
||||
} while(0)
|
||||
|
||||
/*-
|
||||
* The ladder step, with branches, is
|
||||
*
|
||||
* k[i] == 0: S = add(R, S), R = dbl(R)
|
||||
* k[i] == 1: R = add(S, R), S = dbl(S)
|
||||
*
|
||||
* Swapping R, S conditionally on k[i] leaves you with state
|
||||
*
|
||||
* k[i] == 0: T, U = R, S
|
||||
* k[i] == 1: T, U = S, R
|
||||
*
|
||||
* Then perform the ECC ops.
|
||||
*
|
||||
* U = add(T, U)
|
||||
* T = dbl(T)
|
||||
*
|
||||
* Which leaves you with state
|
||||
*
|
||||
* k[i] == 0: U = add(R, S), T = dbl(R)
|
||||
* k[i] == 1: U = add(S, R), T = dbl(S)
|
||||
*
|
||||
* Swapping T, U conditionally on k[i] leaves you with state
|
||||
*
|
||||
* k[i] == 0: R, S = T, U
|
||||
* k[i] == 1: R, S = U, T
|
||||
*
|
||||
* Which leaves you with state
|
||||
*
|
||||
* k[i] == 0: S = add(R, S), R = dbl(R)
|
||||
* k[i] == 1: R = add(S, R), S = dbl(S)
|
||||
*
|
||||
* So we get the same logic, but instead of a branch it's a
|
||||
* conditional swap, followed by ECC ops, then another conditional swap.
|
||||
*
|
||||
* Optimization: The end of iteration i and start of i-1 looks like
|
||||
*
|
||||
* ...
|
||||
* CSWAP(k[i], R, S)
|
||||
* ECC
|
||||
* CSWAP(k[i], R, S)
|
||||
* (next iteration)
|
||||
* CSWAP(k[i-1], R, S)
|
||||
* ECC
|
||||
* CSWAP(k[i-1], R, S)
|
||||
* ...
|
||||
*
|
||||
* So instead of two contiguous swaps, you can merge the condition
|
||||
* bits and do a single swap.
|
||||
*
|
||||
* k[i] k[i-1] Outcome
|
||||
* 0 0 No Swap
|
||||
* 0 1 Swap
|
||||
* 1 0 Swap
|
||||
* 1 1 No Swap
|
||||
*
|
||||
* This is XOR. pbit tracks the previous bit of k.
|
||||
*/
|
||||
|
||||
for (i = order_bits - 1; i >= 0; i--) {
|
||||
kbit = BN_is_bit_set(k, i) ^ pbit;
|
||||
EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
|
||||
if (!EC_POINT_add(group, s, r, s, ctx))
|
||||
goto err;
|
||||
if (!EC_POINT_dbl(group, r, r, ctx))
|
||||
goto err;
|
||||
/*
|
||||
* pbit logic merges this cswap with that of the
|
||||
* next iteration
|
||||
*/
|
||||
pbit ^= kbit;
|
||||
}
|
||||
/* one final cswap to move the right value into r */
|
||||
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
|
||||
#undef EC_POINT_CSWAP
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(s);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef EC_POINT_BN_set_flags
|
||||
|
||||
/*
|
||||
* TODO: table should be optimised for the wNAF-based implementation,
|
||||
* sometimes smaller windows will give better performance (thus the
|
||||
@@ -160,6 +377,32 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Handle the common cases where the scalar is secret, enforcing a constant
|
||||
* time scalar multiplication algorithm.
|
||||
*/
|
||||
if ((scalar != NULL) && (num == 0)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GeneratorPoint: this
|
||||
* codepath is reached most prominently by (ephemeral) key generation
|
||||
* of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH
|
||||
* keygen/first half), where the scalar is always secret. This is why
|
||||
* we ignore if BN_FLG_CONSTTIME is actually set and we always call the
|
||||
* constant time version.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalar, NULL, ctx);
|
||||
}
|
||||
if ((scalar == NULL) && (num == 1)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GenericPoint: this codepath
|
||||
* is reached most prominently by the second half of ECDH, where the
|
||||
* secret scalar is multiplied by the peer's public point. To protect
|
||||
* the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and
|
||||
* we always call the constant time version.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (group->meth != points[i]->meth) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -144,12 +144,14 @@ size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
|
||||
len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
buf = OPENSSL_malloc(len);
|
||||
if (buf == NULL)
|
||||
if ((buf = OPENSSL_malloc(len)) == NULL) {
|
||||
ECerr(EC_F_EC_POINT_POINT2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
|
||||
+118
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -16,6 +16,10 @@
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
#if !defined(OPENSSL_NO_SM2)
|
||||
# include <openssl/sm2.h>
|
||||
#endif
|
||||
|
||||
/* EC pkey context structure */
|
||||
|
||||
typedef struct {
|
||||
@@ -42,9 +46,10 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EC_PKEY_CTX *dctx;
|
||||
|
||||
dctx = OPENSSL_zalloc(sizeof(*dctx));
|
||||
if (dctx == NULL)
|
||||
if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dctx->cofactor_mode = -1;
|
||||
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
|
||||
@@ -102,6 +107,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
unsigned int sltmp;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
|
||||
if (!sig) {
|
||||
*siglen = ECDSA_size(ec);
|
||||
@@ -116,7 +122,15 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
else
|
||||
type = NID_sha1;
|
||||
|
||||
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
|
||||
if (ec_nid == NID_sm2) {
|
||||
#if defined(OPENSSL_NO_SM2)
|
||||
ret = -1;
|
||||
#else
|
||||
ret = SM2_sign(type, tbs, tbslen, sig, &sltmp, ec);
|
||||
#endif
|
||||
} else {
|
||||
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
|
||||
}
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
@@ -131,20 +145,28 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
||||
int ret, type;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
|
||||
if (dctx->md)
|
||||
type = EVP_MD_type(dctx->md);
|
||||
else
|
||||
type = NID_sha1;
|
||||
|
||||
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
|
||||
if (ec_nid == NID_sm2) {
|
||||
#if defined(OPENSSL_NO_SM2)
|
||||
ret = -1;
|
||||
#else
|
||||
ret = SM2_verify(type, tbs, tbslen, sig, siglen, ec);
|
||||
#endif
|
||||
} else {
|
||||
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
|
||||
{
|
||||
int ret;
|
||||
size_t outlen;
|
||||
@@ -180,6 +202,85 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecies_encrypt(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen)
|
||||
{
|
||||
int ret;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
|
||||
if (ec_nid == NID_sm2) {
|
||||
# if defined(OPENSSL_NO_SM2)
|
||||
ret = -1;
|
||||
# else
|
||||
int md_type;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
|
||||
if (dctx->md)
|
||||
md_type = EVP_MD_type(dctx->md);
|
||||
else if (ec_nid == NID_sm2)
|
||||
md_type = NID_sm3;
|
||||
else
|
||||
md_type = NID_sha256;
|
||||
|
||||
if (out == NULL) {
|
||||
*outlen = SM2_ciphertext_size(ec, EVP_get_digestbynid(md_type),
|
||||
inlen);
|
||||
ret = 1;
|
||||
}
|
||||
else {
|
||||
ret = SM2_encrypt(ec, EVP_get_digestbynid(md_type),
|
||||
in, inlen, out, outlen);
|
||||
}
|
||||
# endif
|
||||
} else {
|
||||
/* standard ECIES not implemented */
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pkey_ecies_decrypt(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen)
|
||||
{
|
||||
int ret;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
|
||||
if (ec_nid == NID_sm2) {
|
||||
# if defined(OPENSSL_NO_SM2)
|
||||
ret = -1;
|
||||
# else
|
||||
int md_type;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
|
||||
if (dctx->md)
|
||||
md_type = EVP_MD_type(dctx->md);
|
||||
else if (ec_nid == NID_sm2)
|
||||
md_type = NID_sm3;
|
||||
else
|
||||
md_type = NID_sha256;
|
||||
|
||||
if (out == NULL) {
|
||||
*outlen = SM2_plaintext_size(ec, EVP_get_digestbynid(md_type), inlen);
|
||||
ret = 1;
|
||||
}
|
||||
else {
|
||||
ret = SM2_decrypt(ec, EVP_get_digestbynid(md_type),
|
||||
in, inlen, out, outlen);
|
||||
}
|
||||
# endif
|
||||
} else {
|
||||
/* standard ECIES not implemented */
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *key, size_t *keylen)
|
||||
{
|
||||
@@ -197,9 +298,10 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
return 0;
|
||||
if (!pkey_ec_derive(ctx, NULL, &ktmplen))
|
||||
return 0;
|
||||
ktmp = OPENSSL_malloc(ktmplen);
|
||||
if (ktmp == NULL)
|
||||
if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
|
||||
goto err;
|
||||
/* Do KDF stuff */
|
||||
@@ -244,8 +346,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return dctx->cofactor_mode;
|
||||
else {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
|
||||
0;
|
||||
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
|
||||
}
|
||||
} else if (p1 < -1 || p1 > 1)
|
||||
return -2;
|
||||
@@ -318,7 +419,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sm3) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
}
|
||||
@@ -448,9 +550,11 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
|
||||
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0,
|
||||
0,
|
||||
pkey_ecies_encrypt,
|
||||
|
||||
0, 0,
|
||||
0,
|
||||
pkey_ecies_decrypt,
|
||||
|
||||
0,
|
||||
#ifndef OPENSSL_NO_EC
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
|
||||
@@ -39,9 +40,10 @@ EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
|
||||
|
||||
if ((buf_len = BN_num_bytes(bn)) == 0)
|
||||
return NULL;
|
||||
buf = OPENSSL_malloc(buf_len);
|
||||
if (buf == NULL)
|
||||
if ((buf = OPENSSL_malloc(buf_len)) == NULL) {
|
||||
ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!BN_bn2bin(bn, buf)) {
|
||||
OPENSSL_free(buf);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -40,7 +40,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
EC_POINT *tmp = NULL;
|
||||
BIGNUM *x = NULL, *y = NULL;
|
||||
BIGNUM *x = NULL;
|
||||
const BIGNUM *priv_key;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
@@ -51,8 +51,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL) {
|
||||
if (x == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
@@ -86,14 +85,14 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
|
||||
NID_X9_62_prime_field) {
|
||||
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
|
||||
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
else {
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -105,23 +105,6 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
}
|
||||
while (BN_is_zero(k));
|
||||
|
||||
/*
|
||||
* We do not want timing information to leak the length of k, so we
|
||||
* compute G*k using an equivalent scalar of fixed bit-length.
|
||||
*
|
||||
* We unconditionally perform both of these additions to prevent a
|
||||
* small timing information leakage. We then choose the sum that is
|
||||
* one bit longer than the order. This guarantees the code
|
||||
* path used in the constant time implementations elsewhere.
|
||||
*
|
||||
* TODO: revisit the BN_copy aiming for a memory access agnostic
|
||||
* conditional copy.
|
||||
*/
|
||||
if (!BN_add(r, k, order)
|
||||
|| !BN_add(X, r, order)
|
||||
|| !BN_copy(k, BN_num_bits(r) > order_bits ? r : X))
|
||||
goto err;
|
||||
|
||||
/* compute r the x-coordinate of generator * k */
|
||||
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
|
||||
+14
-18
@@ -45,7 +45,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
# else
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# error "Your compiler doesn't appear to support 128-bit integer types"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
@@ -395,22 +395,6 @@ static void felem_sum(felem out, const felem in)
|
||||
out[3] += in[3];
|
||||
}
|
||||
|
||||
/* Get negative value: out = -in */
|
||||
/* Assumes in[i] < 2^57 */
|
||||
static void felem_neg(felem out, const felem in)
|
||||
{
|
||||
static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
|
||||
static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
|
||||
static const limb two58m42m2 = (((limb) 1) << 58) -
|
||||
(((limb) 1) << 42) - (((limb) 1) << 2);
|
||||
|
||||
/* Set to 0 mod 2^224-2^96+1 to ensure out > in */
|
||||
out[0] = two58p2 - in[0];
|
||||
out[1] = two58m42m2 - in[1];
|
||||
out[2] = two58m2 - in[2];
|
||||
out[3] = two58m2 - in[3];
|
||||
}
|
||||
|
||||
/* Subtract field elements: out -= in */
|
||||
/* Assumes in[i] < 2^57 */
|
||||
static void felem_diff(felem out, const felem in)
|
||||
@@ -679,6 +663,18 @@ static void felem_contract(felem out, const felem in)
|
||||
out[3] = tmp[3];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get negative value: out = -in
|
||||
* Requires in[i] < 2^63,
|
||||
* ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
|
||||
*/
|
||||
static void felem_neg(felem out, const felem in)
|
||||
{
|
||||
widefelem tmp = {0};
|
||||
felem_diff_128_64(tmp, in);
|
||||
felem_reduce(out, tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
|
||||
* elements are reduced to in < 2^225, so we only need to check three cases:
|
||||
@@ -817,7 +813,7 @@ static void copy_conditional(felem out, const felem in, limb icopy)
|
||||
* Double an elliptic curve point:
|
||||
* (X', Y', Z') = 2 * (X, Y, Z), where
|
||||
* X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
|
||||
* Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
|
||||
* Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^4
|
||||
* Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
|
||||
* Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
|
||||
* while x_out == y_in is not (maybe this works, but it's not tested).
|
||||
|
||||
@@ -47,7 +47,7 @@ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
typedef __int128_t int128_t;
|
||||
# else
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# error "Your compiler doesn't appear to support 128-bit integer types"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
|
||||
@@ -45,7 +45,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
# else
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# error "Your compiler doesn't appear to support 128-bit integer types"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
|
||||
+114
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -341,6 +341,19 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
}
|
||||
}
|
||||
|
||||
static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
|
||||
KEY_OP_PRIVATE);
|
||||
}
|
||||
|
||||
static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
|
||||
{
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
|
||||
KEY_OP_PUBLIC);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
@@ -368,7 +381,18 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
ecx_free,
|
||||
ecx_ctrl,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
@@ -398,7 +422,18 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
ecx_free,
|
||||
ecx_ctrl,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
};
|
||||
|
||||
static int ecd_size25519(const EVP_PKEY *pkey)
|
||||
@@ -504,7 +539,14 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
NULL,
|
||||
ecd_item_verify,
|
||||
ecd_item_sign25519,
|
||||
ecd_sig_info_set25519
|
||||
ecd_sig_info_set25519,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
@@ -537,7 +579,14 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
NULL,
|
||||
ecd_item_verify,
|
||||
ecd_item_sign448,
|
||||
ecd_sig_info_set448
|
||||
ecd_sig_info_set448,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
@@ -626,18 +675,18 @@ const EVP_PKEY_METHOD ecx448_pkey_meth = {
|
||||
0
|
||||
};
|
||||
|
||||
static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
static int pkey_ecd_sign25519(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = ctx->pkey->pkey.ecx;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
if (*siglen < ED25519_SIGSIZE) {
|
||||
ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
|
||||
ECerr(EC_F_PKEY_ECD_SIGN25519, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -647,18 +696,26 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
return pkey_ecd_sign25519(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs,
|
||||
tbslen);
|
||||
}
|
||||
|
||||
static int pkey_ecd_sign448(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = ctx->pkey->pkey.ecx;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED448_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
if (*siglen < ED448_SIGSIZE) {
|
||||
ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
|
||||
ECerr(EC_F_PKEY_ECD_SIGN448, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -669,11 +726,18 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
return pkey_ecd_sign448(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs, tbslen);
|
||||
}
|
||||
|
||||
static int pkey_ecd_verify25519(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = ctx->pkey->pkey.ecx;
|
||||
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
@@ -681,11 +745,19 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
return pkey_ecd_verify25519(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs,
|
||||
tbslen);
|
||||
}
|
||||
|
||||
static int pkey_ecd_verify448(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = ctx->pkey->pkey.ecx;
|
||||
|
||||
if (siglen != ED448_SIGSIZE)
|
||||
return 0;
|
||||
@@ -693,12 +765,20 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0);
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
return pkey_ecd_verify448(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs,
|
||||
tbslen);
|
||||
}
|
||||
|
||||
static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
switch (type) {
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
/* Only NULL allowed as digest */
|
||||
if (p2 == NULL)
|
||||
if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
|
||||
return 1;
|
||||
ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
@@ -713,7 +793,11 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = {
|
||||
EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_keygen,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
pkey_ecd_sign25519,
|
||||
0,
|
||||
pkey_ecd_verify25519,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecd_ctrl,
|
||||
0,
|
||||
pkey_ecd_digestsign25519,
|
||||
@@ -724,7 +808,11 @@ const EVP_PKEY_METHOD ed448_pkey_meth = {
|
||||
EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_keygen,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
pkey_ecd_sign448,
|
||||
0,
|
||||
pkey_ecd_verify448,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecd_ctrl,
|
||||
0,
|
||||
pkey_ecd_digestsign448,
|
||||
|
||||
Reference in New Issue
Block a user