Latest update.
This commit is contained in:
@@ -54,6 +54,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
push(@INC,"${dir}","${dir}../../perlasm");
|
||||
require "x86_64-support.pl";
|
||||
|
||||
$ptr_size=&pointer_size($flavour);
|
||||
|
||||
$avx=0;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
@@ -88,6 +93,8 @@ $inp="%rdi"; # 1st arg
|
||||
$key="%rsi"; # 2nd arg
|
||||
$num="%edx";
|
||||
|
||||
$inp_elm_size=2*$ptr_size+8+16;
|
||||
|
||||
@inptr=map("%r$_",(8..11));
|
||||
@outptr=map("%r$_",(12..15));
|
||||
|
||||
@@ -163,21 +170,25 @@ $code.=<<___;
|
||||
.Lenc4x_body:
|
||||
movdqu ($key),$zero # 0-round key
|
||||
lea 0x78($key),$key # size optimization
|
||||
lea 40*2($inp),$inp
|
||||
lea $inp_elm_size*2($inp),$inp
|
||||
|
||||
.Lenc4x_loop_grande:
|
||||
mov $num,24(%rsp) # original $num
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$inptr_reg=&pointer_register($flavour,@inptr[$i]);
|
||||
$outptr_reg=&pointer_register($flavour,@outptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `40*$i+16-40*2`($inp),$one # borrow $one for number of blocks
|
||||
mov `40*$i+0-40*2`($inp),@inptr[$i]
|
||||
# borrow $one for number of blocks
|
||||
mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one
|
||||
mov `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg
|
||||
cmp $num,$one
|
||||
mov `40*$i+8-40*2`($inp),@outptr[$i]
|
||||
mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg
|
||||
cmovg $one,$num # find maximum
|
||||
test $one,$one
|
||||
movdqu `40*$i+24-40*2`($inp),@out[$i] # load IV
|
||||
# load IV
|
||||
movdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@out[$i]
|
||||
mov $one,`32+4*$i`(%rsp) # initialize counters
|
||||
cmovle %rsp,@inptr[$i] # cancel input
|
||||
___
|
||||
@@ -335,14 +346,15 @@ $code.=<<___;
|
||||
|
||||
#pxor @inp[0],@out[0]
|
||||
#pxor @inp[1],@out[1]
|
||||
#movdqu @out[0],`40*0+24-40*2`($inp) # output iv FIX ME!
|
||||
# output iv FIX ME!
|
||||
#movdqu @out[0],`$inp_elm_size*0+2*$ptr_size+8-$inp_elm_size*2`($inp)
|
||||
#pxor @inp[2],@out[2]
|
||||
#movdqu @out[1],`40*1+24-40*2`($inp)
|
||||
#movdqu @out[1],`$inp_elm_size*1+2*$ptr_size+8-$inp_elm_size*2`($inp)
|
||||
#pxor @inp[3],@out[3]
|
||||
#movdqu @out[2],`40*2+24-40*2`($inp) # won't fix, let caller
|
||||
#movdqu @out[3],`40*3+24-40*2`($inp) # figure this out...
|
||||
#movdqu @out[2],`$inp_elm_size*2+2*$ptr_size+8-$inp_elm_size*2`($inp) # won't fix, let caller
|
||||
#movdqu @out[3],`$inp_elm_size*3+2*$ptr_size+8-$inp_elm_size*2`($inp) # figure this out...
|
||||
|
||||
lea `40*4`($inp),$inp
|
||||
lea `$inp_elm_size*4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Lenc4x_loop_grande
|
||||
|
||||
@@ -440,21 +452,25 @@ $code.=<<___;
|
||||
.Ldec4x_body:
|
||||
movdqu ($key),$zero # 0-round key
|
||||
lea 0x78($key),$key # size optimization
|
||||
lea 40*2($inp),$inp
|
||||
lea $inp_elm_size*2($inp),$inp
|
||||
|
||||
.Ldec4x_loop_grande:
|
||||
mov $num,24(%rsp) # original $num
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$inptr_reg=&pointer_register($flavour,@inptr[$i]);
|
||||
$outptr_reg=&pointer_register($flavour,@outptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `40*$i+16-40*2`($inp),$one # borrow $one for number of blocks
|
||||
mov `40*$i+0-40*2`($inp),@inptr[$i]
|
||||
# borrow $one for number of blocks
|
||||
mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one
|
||||
mov `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg
|
||||
cmp $num,$one
|
||||
mov `40*$i+8-40*2`($inp),@outptr[$i]
|
||||
mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg
|
||||
cmovg $one,$num # find maximum
|
||||
test $one,$one
|
||||
movdqu `40*$i+24-40*2`($inp),@inp[$i] # load IV
|
||||
# load IV
|
||||
movdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@inp[$i]
|
||||
mov $one,`32+4*$i`(%rsp) # initialize counters
|
||||
cmovle %rsp,@inptr[$i] # cancel input
|
||||
___
|
||||
@@ -610,7 +626,7 @@ $code.=<<___;
|
||||
.cfi_def_cfa %rax,8
|
||||
mov 24(%rsp),$num
|
||||
|
||||
lea `40*4`($inp),$inp
|
||||
lea `$inp_elm_size*4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Ldec4x_loop_grande
|
||||
|
||||
@@ -709,7 +725,7 @@ $code.=<<___;
|
||||
vzeroupper
|
||||
vmovdqu ($key),$zero # 0-round key
|
||||
lea 0x78($key),$key # size optimization
|
||||
lea 40*4($inp),$inp
|
||||
lea `$inp_elm_size*4`($inp),$inp
|
||||
shr \$1,$num
|
||||
|
||||
.Lenc8x_loop_grande:
|
||||
@@ -718,14 +734,20 @@ $code.=<<___;
|
||||
___
|
||||
for($i=0;$i<8;$i++) {
|
||||
my $temp = $i ? $offload : $offset;
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$temp_reg=&pointer_register($flavour,$temp);
|
||||
$code.=<<___;
|
||||
mov `40*$i+16-40*4`($inp),$one # borrow $one for number of blocks
|
||||
mov `40*$i+0-40*4`($inp),@ptr[$i] # input pointer
|
||||
# borrow $one for number of blocks
|
||||
mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg
|
||||
cmp $num,$one
|
||||
mov `40*$i+8-40*4`($inp),$temp # output pointer
|
||||
# output pointer
|
||||
mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg
|
||||
cmovg $one,$num # find maximum
|
||||
test $one,$one
|
||||
vmovdqu `40*$i+24-40*4`($inp),@out[$i] # load IV
|
||||
# load IV
|
||||
vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i]
|
||||
mov $one,`32+4*$i`(%rsp) # initialize counters
|
||||
cmovle %rsp,@ptr[$i] # cancel input
|
||||
sub @ptr[$i],$temp # distance between input and output
|
||||
@@ -910,7 +932,7 @@ $code.=<<___;
|
||||
mov 16(%rsp),%rax # original %rsp
|
||||
.cfi_def_cfa %rax,8
|
||||
#mov 24(%rsp),$num
|
||||
#lea `40*8`($inp),$inp
|
||||
#lea `$inp_elm_size*8`($inp),$inp
|
||||
#dec $num
|
||||
#jnz .Lenc8x_loop_grande
|
||||
|
||||
@@ -1002,7 +1024,7 @@ $code.=<<___;
|
||||
vzeroupper
|
||||
vmovdqu ($key),$zero # 0-round key
|
||||
lea 0x78($key),$key # size optimization
|
||||
lea 40*4($inp),$inp
|
||||
lea `$inp_elm_size*4`($inp),$inp
|
||||
shr \$1,$num
|
||||
|
||||
.Ldec8x_loop_grande:
|
||||
@@ -1011,14 +1033,20 @@ $code.=<<___;
|
||||
___
|
||||
for($i=0;$i<8;$i++) {
|
||||
my $temp = $i ? $offload : $offset;
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$temp_reg=&pointer_register($flavour,$temp);
|
||||
$code.=<<___;
|
||||
mov `40*$i+16-40*4`($inp),$one # borrow $one for number of blocks
|
||||
mov `40*$i+0-40*4`($inp),@ptr[$i] # input pointer
|
||||
# borrow $one for number of blocks
|
||||
mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg
|
||||
cmp $num,$one
|
||||
mov `40*$i+8-40*4`($inp),$temp # output pointer
|
||||
# output pointer
|
||||
mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg
|
||||
cmovg $one,$num # find maximum
|
||||
test $one,$one
|
||||
vmovdqu `40*$i+24-40*4`($inp),@out[$i] # load IV
|
||||
# load IV
|
||||
vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i]
|
||||
mov $one,`32+4*$i`(%rsp) # initialize counters
|
||||
cmovle %rsp,@ptr[$i] # cancel input
|
||||
sub @ptr[$i],$temp # distance between input and output
|
||||
@@ -1234,7 +1262,7 @@ $code.=<<___;
|
||||
mov 16(%rsp),%rax # original %rsp
|
||||
.cfi_def_cfa %rax,8
|
||||
#mov 24(%rsp),$num
|
||||
#lea `40*8`($inp),$inp
|
||||
#lea `$inp_elm_size*8`($inp),$inp
|
||||
#dec $num
|
||||
#jnz .Ldec8x_loop_grande
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#ifndef NO_ASN1_OLD
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
|
||||
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
|
||||
unsigned char *md, unsigned int *len)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
|
||||
#ifndef NO_ASN1_OLD
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
|
||||
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
|
||||
ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
|
||||
#ifndef NO_ASN1_OLD
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
|
||||
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
|
||||
char *data, EVP_PKEY *pkey)
|
||||
|
||||
@@ -30,7 +30,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (a->pkeys[0].keymgmt != NULL) {
|
||||
if (a->keymgmt != NULL) {
|
||||
const char *serprop = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ;
|
||||
OSSL_SERIALIZER_CTX *ctx =
|
||||
OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
|
||||
|
||||
+1
-86
@@ -397,93 +397,8 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time)
|
||||
FD_ZERO(&confds);
|
||||
openssl_fdset(fd, &confds);
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = (long)(max_time - now); /* this might overflow */
|
||||
tv.tv_sec = (long)(max_time - now); /* might overflow */
|
||||
return select(fd + 1, for_read ? &confds : NULL,
|
||||
for_read ? NULL : &confds, NULL, &tv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on BIO at most until max_time; succeed immediately if max_time == 0.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
static int bio_wait(BIO *bio, time_t max_time)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (BIO_get_fd(bio, &fd) <= 0)
|
||||
return -1;
|
||||
return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on BIO at most until max_time; succeed immediately if max_time == 0.
|
||||
* Call BIOerr(...) unless success.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_wait(BIO *bio, time_t max_time)
|
||||
{
|
||||
int rv = bio_wait(bio, max_time);
|
||||
|
||||
if (rv <= 0)
|
||||
BIOerr(0, rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect via the given BIO using BIO_do_connect() until success/timeout/error.
|
||||
* Parameter timeout == 0 means infinite, < 0 leads to immediate timeout error.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_connect_retry(BIO *bio, int timeout)
|
||||
{
|
||||
int blocking = timeout == 0;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
int rv;
|
||||
|
||||
if (bio == NULL) {
|
||||
BIOerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout < 0) {
|
||||
BIOerr(0, BIO_R_CONNECT_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!blocking)
|
||||
BIO_set_nbio(bio, 1);
|
||||
|
||||
retry: /* it does not help here to set SSL_MODE_AUTO_RETRY */
|
||||
rv = BIO_do_connect(bio); /* This indirectly calls ERR_clear_error(); */
|
||||
|
||||
if (rv <= 0) {
|
||||
if (get_last_sys_error() == ETIMEDOUT) {
|
||||
/*
|
||||
* if blocking, despite blocking BIO, BIO_do_connect() timed out
|
||||
* when non-blocking, BIO_do_connect() timed out early
|
||||
* with rv == -1 and get_last_sys_error() == 0
|
||||
*/
|
||||
ERR_clear_error();
|
||||
(void)BIO_reset(bio);
|
||||
/*
|
||||
* unless using BIO_reset(), blocking next connect() may crash and
|
||||
* non-blocking next BIO_do_connect() will fail
|
||||
*/
|
||||
goto retry;
|
||||
} else if (BIO_should_retry(bio)) {
|
||||
/* will not actually wait if timeout == 0 (i.e., blocking BIO) */
|
||||
rv = bio_wait(bio, max_time);
|
||||
if (rv > 0)
|
||||
goto retry;
|
||||
BIOerr(0, rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
|
||||
} else {
|
||||
rv = -1;
|
||||
if (ERR_peek_error() == 0) /* missing error queue entry */
|
||||
BIOerr(0, BIO_R_CONNECT_ERROR); /* workaround: general error */
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif /* !defined(OPENSSL_NO_SOCK) */
|
||||
@@ -784,3 +784,100 @@ void bio_cleanup(void)
|
||||
CRYPTO_THREAD_lock_free(bio_type_lock);
|
||||
bio_type_lock = NULL;
|
||||
}
|
||||
|
||||
/* Internal variant of the below BIO_wait() not calling BIOerr() */
|
||||
static int bio_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (max_time == 0)
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if (BIO_get_fd(bio, &fd) > 0)
|
||||
return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
|
||||
#endif
|
||||
if (milliseconds > 1000) {
|
||||
long sec_diff = (long)(max_time - time(NULL)); /* might overflow */
|
||||
|
||||
if (sec_diff <= 0)
|
||||
return 0; /* timeout */
|
||||
if ((unsigned long)sec_diff < milliseconds / 1000)
|
||||
milliseconds = (unsigned long)sec_diff * 1000;
|
||||
}
|
||||
ossl_sleep(milliseconds);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on (typically socket-based) BIO at most until max_time.
|
||||
* Succeed immediately if max_time == 0. If sockets are not available succeed
|
||||
* after waiting at most given milliseconds in order to avoid a tight busy loop.
|
||||
* Call BIOerr(...) unless success.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
int rv = bio_wait(bio, max_time, milliseconds);
|
||||
|
||||
if (rv <= 0)
|
||||
BIOerr(0, rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect via given BIO using BIO_do_handshake() until success/timeout/error.
|
||||
* Parameter timeout == 0 means infinite, < 0 leads to immediate timeout error.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_connect_retry(BIO *bio, int timeout)
|
||||
{
|
||||
int blocking = timeout == 0;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
int rv;
|
||||
|
||||
if (bio == NULL) {
|
||||
BIOerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout < 0) {
|
||||
BIOerr(0, BIO_R_CONNECT_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!blocking)
|
||||
BIO_set_nbio(bio, 1);
|
||||
|
||||
retry: /* it does not help here to set SSL_MODE_AUTO_RETRY */
|
||||
rv = BIO_do_handshake(bio); /* This indirectly calls ERR_clear_error(); */
|
||||
|
||||
if (rv <= 0) {
|
||||
if (get_last_sys_error() == ETIMEDOUT) {
|
||||
/*
|
||||
* if blocking, despite blocking BIO, BIO_do_handshake() timed out
|
||||
* when non-blocking, BIO_do_handshake() timed out early
|
||||
* with rv == -1 and get_last_sys_error() == 0
|
||||
*/
|
||||
ERR_clear_error();
|
||||
(void)BIO_reset(bio);
|
||||
/*
|
||||
* unless using BIO_reset(), blocking next connect() may crash and
|
||||
* non-blocking next BIO_do_handshake() will fail
|
||||
*/
|
||||
goto retry;
|
||||
} else if (BIO_should_retry(bio)) {
|
||||
/* will not actually wait if timeout == 0 (i.e., blocking BIO) */
|
||||
rv = bio_wait(bio, max_time, 100 /* milliseconds */);
|
||||
if (rv > 0)
|
||||
goto retry;
|
||||
BIOerr(0, rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
|
||||
} else {
|
||||
rv = -1;
|
||||
if (ERR_peek_error() == 0) /* missing error queue entry */
|
||||
BIOerr(0, BIO_R_CONNECT_ERROR); /* workaround: general error */
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
+6
-2
@@ -322,15 +322,19 @@ BIGNUM *BN_dup(const BIGNUM *a)
|
||||
|
||||
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
|
||||
{
|
||||
int bn_words;
|
||||
|
||||
bn_check_top(b);
|
||||
|
||||
bn_words = BN_get_flags(b, BN_FLG_CONSTTIME) ? b->dmax : b->top;
|
||||
|
||||
if (a == b)
|
||||
return a;
|
||||
if (bn_wexpand(a, b->top) == NULL)
|
||||
if (bn_wexpand(a, bn_words) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (b->top > 0)
|
||||
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
|
||||
memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words);
|
||||
|
||||
a->neg = b->neg;
|
||||
a->top = b->top;
|
||||
|
||||
+2
-2
@@ -61,9 +61,9 @@ ENDIF
|
||||
|
||||
# The Core
|
||||
$CORE_COMMON=provider_core.c provider_predefined.c \
|
||||
core_fetch.c core_algorithm.c core_namemap.c
|
||||
core_fetch.c core_algorithm.c core_namemap.c self_test_core.c
|
||||
|
||||
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c self_test_core.c
|
||||
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
|
||||
SOURCE[../providers/libfips.a]=$CORE_COMMON
|
||||
|
||||
# Central utilities
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
/* This file contains deprecated functions as wrappers to the new ones */
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_DEPRECATED_0_9_8
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
|
||||
+12
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -12,6 +12,17 @@
|
||||
* dh_depr.c as wrappers to these ones. - Geoff
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*
|
||||
* NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
|
||||
* states that no additional pairwise tests are required (apart from the tests
|
||||
* specified in SP800-56A) when generating keys. Hence DH pairwise tests are
|
||||
* omitted here.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
/* DH parameters from RFC7919 and RFC3526 */
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include "dh_local.h"
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* DSA low level APIs are deprecated for public use, but still ok for
|
||||
* DH & DSA low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
|
||||
+22
-17
@@ -15,31 +15,37 @@
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_OID 0x06
|
||||
|
||||
/* dsaWithSHA OIDs are of the form: (1 3 14 3 2 |n|) */
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SHA(name, n) \
|
||||
/*
|
||||
* id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3
|
||||
* }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_RFC3279(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x07, \
|
||||
ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, n \
|
||||
ASN1_SEQUENCE, 0x09, \
|
||||
ASN1_OID, 0x07, 1 * 40 + 2, 134, 72, 206, 56, 4, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHA(sha, 13);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHA(sha1, 27);
|
||||
ENCODE_ALGORITHMIDENTIFIER_RFC3279(sha1, 3);
|
||||
|
||||
/* dsaWithSHA OIDs are of the form: (2 16 840 1 101 3 4 3 |n|) */
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SHAx(name, n) \
|
||||
/*
|
||||
* dsaWithSHAx OIDs are of the form: (sigAlgs |n|)
|
||||
* where sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0b, \
|
||||
ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha224, 1);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha256, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha384, 3);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha512, 4);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_224, 5);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_256, 6);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_384, 7);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_512, 8);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha224, 1);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha256, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha384, 3);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha512, 4);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 5);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 6);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 7);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 8);
|
||||
|
||||
#define MD_CASE(name) \
|
||||
case NID_##name: \
|
||||
@@ -49,7 +55,6 @@ ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_512, 8);
|
||||
const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (md_nid) {
|
||||
MD_CASE(sha);
|
||||
MD_CASE(sha1);
|
||||
MD_CASE(sha224);
|
||||
MD_CASE(sha256);
|
||||
|
||||
+62
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -17,10 +17,12 @@
|
||||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "crypto/dsa.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa);
|
||||
static int dsa_keygen(DSA *dsa, int pairwise_test);
|
||||
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg);
|
||||
|
||||
int DSA_generate_key(DSA *dsa)
|
||||
{
|
||||
@@ -28,7 +30,7 @@ int DSA_generate_key(DSA *dsa)
|
||||
if (dsa->meth->dsa_keygen != NULL)
|
||||
return dsa->meth->dsa_keygen(dsa);
|
||||
#endif
|
||||
return dsa_builtin_keygen(dsa);
|
||||
return dsa_keygen(dsa, 0);
|
||||
}
|
||||
|
||||
int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key,
|
||||
@@ -50,7 +52,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa)
|
||||
static int dsa_keygen(DSA *dsa, int pairwise_test)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
@@ -82,8 +84,26 @@ static int dsa_builtin_keygen(DSA *dsa)
|
||||
|
||||
dsa->priv_key = priv_key;
|
||||
dsa->pub_key = pub_key;
|
||||
dsa->dirty_cnt++;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
pairwise_test = 1;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ok = 1;
|
||||
if (pairwise_test) {
|
||||
OSSL_CALLBACK *cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg);
|
||||
ok = dsa_keygen_pairwise_test(dsa, cb, cbarg);
|
||||
if (!ok) {
|
||||
BN_free(dsa->pub_key);
|
||||
BN_clear_free(dsa->priv_key);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
dsa->dirty_cnt++;
|
||||
|
||||
err:
|
||||
if (pub_key != dsa->pub_key)
|
||||
@@ -91,5 +111,42 @@ static int dsa_builtin_keygen(DSA *dsa)
|
||||
if (priv_key != dsa->priv_key)
|
||||
BN_free(priv_key);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIPS 140-2 IG 9.9 AS09.33
|
||||
* Perform a sign/verify operation.
|
||||
*/
|
||||
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char dgst[16] = {0};
|
||||
unsigned int dgst_len = (unsigned int)sizeof(dgst);
|
||||
DSA_SIG *sig = NULL;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_DSA);
|
||||
|
||||
sig = DSA_do_sign(dgst, (int)dgst_len, dsa);
|
||||
if (sig == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
|
||||
|
||||
if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
DSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
@@ -337,3 +337,8 @@ int DSA_bits(const DSA *dsa)
|
||||
{
|
||||
return BN_num_bits(dsa->params.p);
|
||||
}
|
||||
|
||||
FFC_PARAMS *dsa_get0_params(DSA *dsa)
|
||||
{
|
||||
return &dsa->params;
|
||||
}
|
||||
@@ -43,8 +43,6 @@ IF[{- !$disabled{asm} -}]
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ec_curve.c ec_check.c ec_print.c ec_key.c ec_asn1.c \
|
||||
ec2_smpl.c \
|
||||
@@ -55,7 +53,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
|
||||
$ECASM
|
||||
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
|
||||
ec_err.c ecdh_kdf.c eck_prn.c
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
|
||||
+174
-3
@@ -22,6 +22,8 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
@@ -29,7 +31,7 @@ static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
|
||||
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
|
||||
#endif
|
||||
|
||||
static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
||||
static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
|
||||
{
|
||||
const EC_GROUP *group;
|
||||
int nid;
|
||||
@@ -63,7 +65,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
||||
|
||||
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec_key = pkey->pkey.ec;
|
||||
const EC_KEY *ec_key = pkey->pkey.ec;
|
||||
void *pval = NULL;
|
||||
int ptype;
|
||||
unsigned char *penc = NULL, *p;
|
||||
@@ -574,6 +576,167 @@ static int ec_pkey_param_check(const EVP_PKEY *pkey)
|
||||
return EC_GROUP_check(eckey->group, NULL);
|
||||
}
|
||||
|
||||
static
|
||||
size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->pkey.ec->dirty_cnt;
|
||||
}
|
||||
|
||||
static ossl_inline
|
||||
int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
{
|
||||
const EC_GROUP *ecg;
|
||||
int curve_nid;
|
||||
|
||||
if (eckey == NULL)
|
||||
return 0;
|
||||
|
||||
ecg = EC_KEY_get0_group(eckey);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
curve_nid = EC_GROUP_get_curve_name(ecg);
|
||||
|
||||
if (curve_nid == NID_undef) {
|
||||
/* explicit parameters */
|
||||
|
||||
/*
|
||||
* TODO(3.0): should we support explicit parameters curves?
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
/* named curve */
|
||||
const char *curve_name = NULL;
|
||||
|
||||
if ((curve_name = OBJ_nid2sn(curve_nid)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
{
|
||||
const EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
unsigned char *pub_key_buf = NULL;
|
||||
size_t pub_key_buflen;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const BIGNUM *priv_key = NULL;
|
||||
const EC_POINT *pub_point = NULL;
|
||||
int rv = 0;
|
||||
|
||||
if (from == NULL
|
||||
|| (eckey = from->pkey.ec) == NULL
|
||||
|| (ecg = EC_KEY_get0_group(eckey)) == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
|
||||
/* export the domain parameters */
|
||||
if (!ecparams_to_params(eckey, &tmpl))
|
||||
return 0;
|
||||
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
pub_point = EC_KEY_get0_public_key(eckey);
|
||||
|
||||
/* public_key must be present, priv_key is optional */
|
||||
if (pub_point == NULL)
|
||||
return 0;
|
||||
|
||||
/* convert pub_point to a octet string according to the SECG standard */
|
||||
if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
|
||||
POINT_CONVERSION_COMPRESSED,
|
||||
&pub_key_buf, NULL)) == 0)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl,
|
||||
OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key_buf,
|
||||
pub_key_buflen))
|
||||
goto err;
|
||||
|
||||
if (priv_key != NULL) {
|
||||
size_t sz;
|
||||
int ecbits;
|
||||
int ecdh_cofactor_mode;
|
||||
|
||||
/*
|
||||
* Key import/export should never leak the bit length of the secret
|
||||
* scalar in the key.
|
||||
*
|
||||
* For this reason, on export we use padded BIGNUMs with fixed length.
|
||||
*
|
||||
* When importing we also should make sure that, even if short lived,
|
||||
* the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
|
||||
* soon as possible, so that any processing of this BIGNUM might opt for
|
||||
* constant time implementations in the backend.
|
||||
*
|
||||
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
|
||||
* to preallocate the BIGNUM internal buffer to a fixed public size big
|
||||
* enough that operations performed during the processing never trigger
|
||||
* a realloc which would leak the size of the scalar through memory
|
||||
* accesses.
|
||||
*
|
||||
* Fixed Length
|
||||
* ------------
|
||||
*
|
||||
* The order of the large prime subgroup of the curve is our choice for
|
||||
* a fixed public size, as that is generally the upper bound for
|
||||
* generating a private key in EC cryptosystems and should fit all valid
|
||||
* secret scalars.
|
||||
*
|
||||
* For padding on export we just use the bit length of the order
|
||||
* converted to bytes (rounding up).
|
||||
*
|
||||
* For preallocating the BIGNUM storage we look at the number of "words"
|
||||
* required for the internal representation of the order, and we
|
||||
* preallocate 2 extra "words" in case any of the subsequent processing
|
||||
* might temporarily overflow the order length.
|
||||
*/
|
||||
ecbits = EC_GROUP_order_bits(ecg);
|
||||
if (ecbits <= 0)
|
||||
goto err;
|
||||
|
||||
sz = (ecbits + 7 ) / 8;
|
||||
if (!ossl_param_bld_push_BN_pad(&tmpl,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key, sz))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* The ECDH Cofactor Mode is defined only if the EC_KEY actually
|
||||
* contains a private key, so we check for the flag and export it only
|
||||
* in this case.
|
||||
*/
|
||||
ecdh_cofactor_mode =
|
||||
(EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
|
||||
|
||||
/* Export the ECDH_COFACTOR_MODE parameter */
|
||||
if (!ossl_param_bld_push_int(&tmpl,
|
||||
OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
|
||||
ecdh_cofactor_mode))
|
||||
goto err;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
err:
|
||||
ossl_param_bld_free(params);
|
||||
OPENSSL_free(pub_key_buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
EVP_PKEY_EC,
|
||||
EVP_PKEY_EC,
|
||||
@@ -611,7 +774,15 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
|
||||
ec_pkey_check,
|
||||
ec_pkey_public_check,
|
||||
ec_pkey_param_check
|
||||
ec_pkey_param_check,
|
||||
|
||||
0, /* set_priv_key */
|
||||
0, /* set_pub_key */
|
||||
0, /* get_priv_key */
|
||||
0, /* get_pub_key */
|
||||
|
||||
ec_pkey_dirty_cnt,
|
||||
ec_pkey_export_to
|
||||
};
|
||||
|
||||
#if !defined(OPENSSL_NO_SM2)
|
||||
|
||||
@@ -1051,6 +1051,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
*a = ret;
|
||||
EC_PRIVATEKEY_free(priv_key);
|
||||
*in = p;
|
||||
ret->dirty_cnt++;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
@@ -1162,8 +1163,11 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
|
||||
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
if (a == NULL || *a != ret)
|
||||
EC_KEY_free(ret);
|
||||
else
|
||||
ret->dirty_cnt++;
|
||||
return NULL;
|
||||
}
|
||||
ret->dirty_cnt++;
|
||||
|
||||
if (a)
|
||||
*a = ret;
|
||||
@@ -1183,6 +1187,7 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
return 0;
|
||||
}
|
||||
ret = *a;
|
||||
/* EC_KEY_opt2key updates dirty_cnt */
|
||||
if (!EC_KEY_oct2key(ret, *in, len, NULL)) {
|
||||
ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include "crypto/evp.h"
|
||||
|
||||
#include "ec_local.h"
|
||||
|
||||
/*
|
||||
* This file is meant to contain functions to provide EVP_PKEY support for EC
|
||||
* keys.
|
||||
*/
|
||||
|
||||
static ossl_inline
|
||||
int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* If key type not EC return error */
|
||||
if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode)
|
||||
{
|
||||
int ret;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Valid input values are:
|
||||
* * 0 for disable
|
||||
* * 1 for enable
|
||||
* * -1 for reset to default for associated priv key
|
||||
*/
|
||||
if (cofactor_mode < -1 || cofactor_mode > 1) {
|
||||
/* Uses the same return value of pkey_ec_ctrl() */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_ECDH_COFACTOR,
|
||||
cofactor_mode, NULL);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
|
||||
&cofactor_mode);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_set_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret, mode;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
|
||||
&mode);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_get_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else if (ret != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode < 0 || mode > 1) {
|
||||
/*
|
||||
* The provider should return either 0 or 1, any other value is a
|
||||
* provider error.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
|
||||
{
|
||||
int ret;
|
||||
const char *kdf_type;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
switch (kdf) {
|
||||
case EVP_PKEY_ECDH_KDF_NONE:
|
||||
kdf_type = "";
|
||||
break;
|
||||
case EVP_PKEY_ECDH_KDF_X9_63:
|
||||
kdf_type = OSSL_KDF_NAME_X963KDF;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)kdf_type, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_set_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
/* 80 should be big enough */
|
||||
char kdf_type[80];
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
|
||||
kdf_type, sizeof(kdf_type));
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_get_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else if (ret != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (kdf_type[0] == '\0')
|
||||
return EVP_PKEY_ECDH_KDF_NONE;
|
||||
else if (strcmp(kdf_type, OSSL_KDF_NAME_X963KDF) == 0)
|
||||
return EVP_PKEY_ECDH_KDF_X9_63;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
int ret;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
const char *md_name = NULL;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md));
|
||||
|
||||
md_name = (md == NULL) ? "" : EVP_MD_name(md);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)md_name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_set_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
|
||||
{
|
||||
/* 80 should be big enough */
|
||||
char name[80] = "";
|
||||
int ret;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd));
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
|
||||
name, sizeof(name));
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_get_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else if (ret != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* May be NULL meaning "unknown" */
|
||||
*pmd = EVP_get_digestbyname(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int in)
|
||||
{
|
||||
int ret;
|
||||
size_t len = in;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_OUTLEN, in, NULL);
|
||||
|
||||
if (in <= 0) {
|
||||
/*
|
||||
* This would ideally be -1 or 0, but we have to retain compatibility
|
||||
* with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
|
||||
* in <= 0
|
||||
*/
|
||||
return -2;
|
||||
}
|
||||
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
|
||||
&len);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_set_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
|
||||
{
|
||||
size_t len = UINT_MAX;
|
||||
int ret;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0,
|
||||
(void *)(plen));
|
||||
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
|
||||
&len);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_get_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else if (ret != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > INT_MAX)
|
||||
return -1;
|
||||
|
||||
*plen = (int)len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
|
||||
{
|
||||
int ret;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_UKM, len, (void *)(ukm));
|
||||
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(void *)ukm,
|
||||
(size_t)len);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_set_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
if (ret == 1)
|
||||
OPENSSL_free(ukm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
|
||||
{
|
||||
size_t ukmlen;
|
||||
int ret;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0,
|
||||
(void *)(pukm));
|
||||
|
||||
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
|
||||
(void **)pukm, 0);
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
|
||||
&ukmlen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = evp_pkey_ctx_get_params_strict(ctx, params);
|
||||
if (ret == -2) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else if (ret != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ukmlen > INT_MAX)
|
||||
return -1;
|
||||
|
||||
return (int)ukmlen;
|
||||
}
|
||||
+182
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
@@ -20,6 +20,11 @@
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "crypto/bn.h"
|
||||
|
||||
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
|
||||
void *cbarg);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
@@ -169,6 +174,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
|
||||
return NULL;
|
||||
|
||||
dest->dirty_cnt++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
@@ -209,15 +216,28 @@ int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (eckey->meth->keygen != NULL)
|
||||
return eckey->meth->keygen(eckey);
|
||||
if (eckey->meth->keygen != NULL) {
|
||||
int ret;
|
||||
|
||||
ret = eckey->meth->keygen(eckey);
|
||||
if (ret == 1)
|
||||
eckey->dirty_cnt++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey)
|
||||
{
|
||||
return eckey->group->meth->keygen(eckey);
|
||||
int ret;
|
||||
|
||||
ret = eckey->group->meth->keygen(eckey);
|
||||
|
||||
if (ret == 1)
|
||||
eckey->dirty_cnt++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -225,11 +245,14 @@ int ossl_ec_key_gen(EC_KEY *eckey)
|
||||
* See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
|
||||
*
|
||||
* Params:
|
||||
* libctx A context containing an optional self test callback.
|
||||
* eckey An EC key object that contains domain params. The generated keypair
|
||||
* is stored in this object.
|
||||
* pairwise_test Set to non zero to perform a pairwise test. If the test
|
||||
* fails then the keypair is not generated,
|
||||
* Returns 1 if the keypair was generated or 0 otherwise.
|
||||
*/
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test)
|
||||
{
|
||||
int ok = 0;
|
||||
BIGNUM *priv_key = NULL;
|
||||
@@ -287,8 +310,20 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
priv_key = NULL;
|
||||
pub_key = NULL;
|
||||
|
||||
ok = 1;
|
||||
eckey->dirty_cnt++;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
pairwise_test = 1;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ok = 1;
|
||||
if (pairwise_test) {
|
||||
OSSL_CALLBACK *cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
|
||||
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
|
||||
}
|
||||
err:
|
||||
/* Step (9): If there is an error return an invalid keypair. */
|
||||
if (!ok) {
|
||||
@@ -303,14 +338,26 @@ err:
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
return ec_generate_key(NULL, eckey, 0);
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* See SP800-56AR3 5.6.1.2.2: Step (8)
|
||||
* pub_key = priv_key * G (where G is a point on the curve)
|
||||
*/
|
||||
return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
|
||||
NULL, NULL);
|
||||
ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
if (ret == 1)
|
||||
eckey->dirty_cnt++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_KEY_check_key(const EC_KEY *eckey)
|
||||
@@ -505,6 +552,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* EC_KEY_set_public_key updates dirty_cnt */
|
||||
if (!EC_KEY_set_public_key(key, point))
|
||||
goto err;
|
||||
|
||||
@@ -532,6 +580,7 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
|
||||
return 0;
|
||||
EC_GROUP_free(key->group);
|
||||
key->group = EC_GROUP_dup(group);
|
||||
key->dirty_cnt++;
|
||||
return (key->group == NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -542,17 +591,87 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
|
||||
|
||||
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
|
||||
{
|
||||
int fixed_top;
|
||||
const BIGNUM *order = NULL;
|
||||
BIGNUM *tmp_key = NULL;
|
||||
|
||||
if (key->group == NULL || key->group->meth == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Not only should key->group be set, but it should also be in a valid
|
||||
* fully initialized state.
|
||||
*
|
||||
* Specifically, to operate in constant time, we need that the group order
|
||||
* is set, as we use its length as the fixed public size of any scalar used
|
||||
* as an EC private key.
|
||||
*/
|
||||
order = EC_GROUP_get0_order(key->group);
|
||||
if (order == NULL || BN_is_zero(order))
|
||||
return 0; /* This should never happen */
|
||||
|
||||
if (key->group->meth->set_private != NULL
|
||||
&& key->group->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
if (key->meth->set_private != NULL
|
||||
&& key->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We should never leak the bit length of the secret scalar in the key,
|
||||
* so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
|
||||
* holding the secret scalar.
|
||||
*
|
||||
* This is important also because `BN_dup()` (and `BN_copy()`) do not
|
||||
* propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
|
||||
* this brings an extra risk of inadvertently losing the flag, even when
|
||||
* the called specifically set it.
|
||||
*
|
||||
* The propagation has been turned on and off a few times in the past
|
||||
* years because in some conditions has shown unintended consequences in
|
||||
* some code paths, so at the moment we can't fix this in the BN layer.
|
||||
*
|
||||
* In `EC_KEY_set_private_key()` we can work around the propagation by
|
||||
* manually setting the flag after `BN_dup()` as we know for sure that
|
||||
* inside the EC module the `BN_FLG_CONSTTIME` is always treated
|
||||
* correctly and should not generate unintended consequences.
|
||||
*
|
||||
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
|
||||
* to preallocate the BIGNUM internal buffer to a fixed public size big
|
||||
* enough that operations performed during the processing never trigger
|
||||
* a realloc which would leak the size of the scalar through memory
|
||||
* accesses.
|
||||
*
|
||||
* Fixed Length
|
||||
* ------------
|
||||
*
|
||||
* The order of the large prime subgroup of the curve is our choice for
|
||||
* a fixed public size, as that is generally the upper bound for
|
||||
* generating a private key in EC cryptosystems and should fit all valid
|
||||
* secret scalars.
|
||||
*
|
||||
* For preallocating the BIGNUM storage we look at the number of "words"
|
||||
* required for the internal representation of the order, and we
|
||||
* preallocate 2 extra "words" in case any of the subsequent processing
|
||||
* might temporarily overflow the order length.
|
||||
*/
|
||||
tmp_key = BN_dup(priv_key);
|
||||
if (tmp_key == NULL)
|
||||
return 0;
|
||||
|
||||
BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
|
||||
|
||||
fixed_top = bn_get_top(order) + 2;
|
||||
if (bn_wexpand(tmp_key, fixed_top) == NULL) {
|
||||
BN_clear_free(tmp_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_clear_free(key->priv_key);
|
||||
key->priv_key = BN_dup(priv_key);
|
||||
return (key->priv_key == NULL) ? 0 : 1;
|
||||
key->priv_key = tmp_key;
|
||||
key->dirty_cnt++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
|
||||
@@ -567,6 +686,7 @@ int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
|
||||
return 0;
|
||||
EC_POINT_free(key->pub_key);
|
||||
key->pub_key = EC_POINT_dup(pub_key, key->group);
|
||||
key->dirty_cnt++;
|
||||
return (key->pub_key == NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -613,11 +733,13 @@ int EC_KEY_get_flags(const EC_KEY *key)
|
||||
void EC_KEY_set_flags(EC_KEY *key, int flags)
|
||||
{
|
||||
key->flags |= flags;
|
||||
key->dirty_cnt++;
|
||||
}
|
||||
|
||||
void EC_KEY_clear_flags(EC_KEY *key, int flags)
|
||||
{
|
||||
key->flags &= ~flags;
|
||||
key->dirty_cnt++;
|
||||
}
|
||||
|
||||
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
|
||||
@@ -639,6 +761,7 @@ int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
|
||||
return 0;
|
||||
if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
|
||||
return 0;
|
||||
key->dirty_cnt++;
|
||||
/*
|
||||
* Save the point conversion form.
|
||||
* For non-custom curves the first octet of the buffer (excluding
|
||||
@@ -689,13 +812,18 @@ size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
|
||||
int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL)
|
||||
return 0;
|
||||
if (eckey->group->meth->oct2priv == NULL) {
|
||||
ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
return eckey->group->meth->oct2priv(eckey, buf, len);
|
||||
ret = eckey->group->meth->oct2priv(eckey, buf, len);
|
||||
if (ret == 1)
|
||||
eckey->dirty_cnt++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
@@ -711,6 +839,7 @@ int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
eckey->dirty_cnt++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -742,3 +871,45 @@ int EC_KEY_can_sign(const EC_KEY *eckey)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIPS 140-2 IG 9.9 AS09.33
|
||||
* Perform a sign/verify operation.
|
||||
*
|
||||
* NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
|
||||
* states that no additional pairwise tests are required (apart from the tests
|
||||
* specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are
|
||||
* omitted here.
|
||||
*/
|
||||
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
|
||||
void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char dgst[16] = {0};
|
||||
int dgst_len = (int)sizeof(dgst);
|
||||
ECDSA_SIG *sig = NULL;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
return 0;
|
||||
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_ECDSA);
|
||||
|
||||
sig = ECDSA_do_sign(dgst, dgst_len, eckey);
|
||||
if (sig == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
|
||||
|
||||
if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
@@ -301,6 +301,9 @@ struct ec_key_st {
|
||||
#endif
|
||||
CRYPTO_RWLOCK *lock;
|
||||
OPENSSL_CTX *libctx;
|
||||
|
||||
/* Provider data */
|
||||
size_t dirty_cnt; /* If any key material changes, increment this */
|
||||
};
|
||||
|
||||
struct ec_point_st {
|
||||
|
||||
@@ -80,8 +80,8 @@ static const felem_bytearray nistp256_curve_params[5] = {
|
||||
{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
|
||||
{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc},
|
||||
{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, /* b */
|
||||
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
|
||||
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
|
||||
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
|
||||
|
||||
@@ -169,12 +169,13 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
|
||||
|
||||
if (r == NULL || kinv == NULL) {
|
||||
/*
|
||||
* Generate random k and copy to param param block. RAND_priv_bytes
|
||||
* Generate random k and copy to param param block. RAND_priv_bytes_ex
|
||||
* is used instead of BN_priv_rand_range or BN_generate_dsa_nonce
|
||||
* because kdsa instruction constructs an in-range, invertible nonce
|
||||
* internally implementing counter-measures for RNG weakness.
|
||||
*/
|
||||
if (RAND_priv_bytes(param + S390X_OFF_RN(len), len) != 1) {
|
||||
if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len),
|
||||
len) != 1) {
|
||||
ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto ret;
|
||||
|
||||
@@ -1132,6 +1132,7 @@ RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking
|
||||
RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate
|
||||
RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy
|
||||
RAND_F_RAND_DRBG_GET_NONCE:123:rand_drbg_get_nonce
|
||||
RAND_F_RAND_DRBG_INIT_METHOD:130:
|
||||
RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate
|
||||
RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new
|
||||
RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed
|
||||
@@ -1767,6 +1768,7 @@ X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname
|
||||
X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED
|
||||
X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING
|
||||
X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER
|
||||
X509V3_F_I2S_ASN1_UTF8STRING:173:
|
||||
X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS
|
||||
X509V3_F_LEVEL_ADD_NODE:168:level_add_node
|
||||
X509V3_F_NOTICE_SECTION:132:notice_section
|
||||
@@ -1781,6 +1783,7 @@ X509V3_F_R2I_PCI:155:r2i_pci
|
||||
X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING
|
||||
X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER
|
||||
X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING
|
||||
X509V3_F_S2I_ASN1_UTF8STRING:174:
|
||||
X509V3_F_S2I_SKEY_ID:115:s2i_skey_id
|
||||
X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name
|
||||
X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc
|
||||
@@ -2752,6 +2755,7 @@ PROP_R_PARSE_FAILED:108:parse failed
|
||||
PROP_R_STRING_TOO_LONG:109:string too long
|
||||
PROP_R_TRAILING_CHARACTERS:110:trailing characters
|
||||
PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed
|
||||
PROV_R_ALGORITHM_MISMATCH:173:algorithm mismatch
|
||||
PROV_R_BAD_DECRYPT:100:bad decrypt
|
||||
PROV_R_BAD_ENCODING:141:bad encoding
|
||||
PROV_R_BAD_LENGTH:142:bad length
|
||||
@@ -2759,17 +2763,21 @@ PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version
|
||||
PROV_R_BN_ERROR:160:bn error
|
||||
PROV_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int
|
||||
PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
|
||||
PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed
|
||||
PROV_R_FAILED_DURING_DERIVATION:164:failed during derivation
|
||||
PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt
|
||||
PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
|
||||
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
|
||||
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
|
||||
PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\
|
||||
illegal or unsupported padding mode
|
||||
PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length
|
||||
PROV_R_INVALID_AAD:108:invalid aad
|
||||
PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length
|
||||
PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
|
||||
PROV_R_INVALID_DATA:115:invalid data
|
||||
PROV_R_INVALID_DIGEST:122:invalid digest
|
||||
PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length
|
||||
PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count
|
||||
PROV_R_INVALID_IVLEN:116:invalid ivlen
|
||||
PROV_R_INVALID_IV_LENGTH:109:invalid iv length
|
||||
@@ -2778,12 +2786,17 @@ PROV_R_INVALID_KEYLEN:117:invalid keylen
|
||||
PROV_R_INVALID_KEY_LEN:124:invalid key len
|
||||
PROV_R_INVALID_KEY_LENGTH:105:invalid key length
|
||||
PROV_R_INVALID_MAC:151:invalid mac
|
||||
PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md
|
||||
PROV_R_INVALID_MODE:125:invalid mode
|
||||
PROV_R_INVALID_MODE_INT:126:invalid mode int
|
||||
PROV_R_INVALID_PADDING_MODE:168:invalid padding mode
|
||||
PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen
|
||||
PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
|
||||
PROV_R_INVALID_SEED_LENGTH:154:invalid seed length
|
||||
PROV_R_INVALID_TAG:110:invalid tag
|
||||
PROV_R_INVALID_TAGLEN:118:invalid taglen
|
||||
PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest
|
||||
PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small
|
||||
PROV_R_MISSING_CEK_ALG:144:missing cek alg
|
||||
PROV_R_MISSING_CIPHER:155:missing cipher
|
||||
PROV_R_MISSING_CONSTANT:156:missing constant
|
||||
@@ -2801,6 +2814,7 @@ PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
|
||||
PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
|
||||
PROV_R_READ_KEY:159:read key
|
||||
PROV_R_TAG_NOTSET:119:tag notset
|
||||
PROV_R_TAG_NOT_NEEDED:120:tag not needed
|
||||
|
||||
@@ -1132,6 +1132,7 @@ RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking
|
||||
RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate
|
||||
RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy
|
||||
RAND_F_RAND_DRBG_GET_NONCE:123:rand_drbg_get_nonce
|
||||
RAND_F_RAND_DRBG_INIT_METHOD:130:
|
||||
RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate
|
||||
RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new
|
||||
RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed
|
||||
@@ -1767,6 +1768,7 @@ X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname
|
||||
X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED
|
||||
X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING
|
||||
X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER
|
||||
X509V3_F_I2S_ASN1_UTF8STRING:173:
|
||||
X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS
|
||||
X509V3_F_LEVEL_ADD_NODE:168:level_add_node
|
||||
X509V3_F_NOTICE_SECTION:132:notice_section
|
||||
@@ -1781,6 +1783,7 @@ X509V3_F_R2I_PCI:155:r2i_pci
|
||||
X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING
|
||||
X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER
|
||||
X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING
|
||||
X509V3_F_S2I_ASN1_UTF8STRING:174:
|
||||
X509V3_F_S2I_SKEY_ID:115:s2i_skey_id
|
||||
X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name
|
||||
X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc
|
||||
@@ -2752,6 +2755,7 @@ PROP_R_PARSE_FAILED:108:parse failed
|
||||
PROP_R_STRING_TOO_LONG:109:string too long
|
||||
PROP_R_TRAILING_CHARACTERS:110:trailing characters
|
||||
PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed
|
||||
PROV_R_ALGORITHM_MISMATCH:173:algorithm mismatch
|
||||
PROV_R_BAD_DECRYPT:100:bad decrypt
|
||||
PROV_R_BAD_ENCODING:141:bad encoding
|
||||
PROV_R_BAD_LENGTH:142:bad length
|
||||
@@ -2759,17 +2763,21 @@ PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version
|
||||
PROV_R_BN_ERROR:160:bn error
|
||||
PROV_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int
|
||||
PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
|
||||
PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed
|
||||
PROV_R_FAILED_DURING_DERIVATION:164:failed during derivation
|
||||
PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt
|
||||
PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
|
||||
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
|
||||
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
|
||||
PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\
|
||||
illegal or unsupported padding mode
|
||||
PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length
|
||||
PROV_R_INVALID_AAD:108:invalid aad
|
||||
PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length
|
||||
PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
|
||||
PROV_R_INVALID_DATA:115:invalid data
|
||||
PROV_R_INVALID_DIGEST:122:invalid digest
|
||||
PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length
|
||||
PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count
|
||||
PROV_R_INVALID_IVLEN:116:invalid ivlen
|
||||
PROV_R_INVALID_IV_LENGTH:109:invalid iv length
|
||||
@@ -2778,12 +2786,17 @@ PROV_R_INVALID_KEYLEN:117:invalid keylen
|
||||
PROV_R_INVALID_KEY_LEN:124:invalid key len
|
||||
PROV_R_INVALID_KEY_LENGTH:105:invalid key length
|
||||
PROV_R_INVALID_MAC:151:invalid mac
|
||||
PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md
|
||||
PROV_R_INVALID_MODE:125:invalid mode
|
||||
PROV_R_INVALID_MODE_INT:126:invalid mode int
|
||||
PROV_R_INVALID_PADDING_MODE:168:invalid padding mode
|
||||
PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen
|
||||
PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
|
||||
PROV_R_INVALID_SEED_LENGTH:154:invalid seed length
|
||||
PROV_R_INVALID_TAG:110:invalid tag
|
||||
PROV_R_INVALID_TAGLEN:118:invalid taglen
|
||||
PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest
|
||||
PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small
|
||||
PROV_R_MISSING_CEK_ALG:144:missing cek alg
|
||||
PROV_R_MISSING_CIPHER:155:missing cipher
|
||||
PROV_R_MISSING_CONSTANT:156:missing constant
|
||||
@@ -2801,6 +2814,7 @@ PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
|
||||
PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
|
||||
PROV_R_READ_KEY:159:read key
|
||||
PROV_R_TAG_NOTSET:119:tag notset
|
||||
PROV_R_TAG_NOT_NEEDED:120:tag not needed
|
||||
@@ -3377,8 +3391,8 @@ X509_R_BAD_SELECTOR:133:bad selector
|
||||
X509_R_BAD_X509_FILETYPE:100:bad x509 filetype
|
||||
X509_R_BASE64_DECODE_ERROR:118:base64 decode error
|
||||
X509_R_CANT_CHECK_DH_KEY:114:cant check dh key
|
||||
X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
|
||||
X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed
|
||||
X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
|
||||
X509_R_CRL_ALREADY_DELTA:127:crl already delta
|
||||
X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
|
||||
X509_R_IDP_MISMATCH:128:idp mismatch
|
||||
|
||||
@@ -534,17 +534,12 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
|
||||
static long b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return BIO_callback_ctrl(next, cmd, fp);
|
||||
}
|
||||
|
||||
static int b64_puts(BIO *b, const char *str)
|
||||
|
||||
@@ -388,17 +388,12 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
|
||||
static long enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return BIO_callback_ctrl(next, cmd, fp);
|
||||
}
|
||||
|
||||
int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
|
||||
|
||||
+1
-7
@@ -197,7 +197,6 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
|
||||
static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next;
|
||||
|
||||
next = BIO_next(b);
|
||||
@@ -205,12 +204,7 @@ static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
return BIO_callback_ctrl(next, cmd, fp);
|
||||
}
|
||||
|
||||
static int md_gets(BIO *bp, char *buf, int size)
|
||||
|
||||
+1
-8
@@ -406,7 +406,6 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
|
||||
static long ok_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next;
|
||||
|
||||
next = BIO_next(b);
|
||||
@@ -414,13 +413,7 @@ static long ok_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return BIO_callback_ctrl(next, cmd, fp);
|
||||
}
|
||||
|
||||
static void longswap(void *_ptr, size_t len)
|
||||
|
||||
@@ -373,7 +373,7 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
ossl_algorithm_do_all(libctx, operation_id, NULL, do_one, &data);
|
||||
}
|
||||
|
||||
const char *evp_first_name(OSSL_PROVIDER *prov, int name_id)
|
||||
const char *evp_first_name(const OSSL_PROVIDER *prov, int name_id)
|
||||
{
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
@@ -78,17 +78,21 @@ struct evp_keymgmt_st {
|
||||
OSSL_OP_keymgmt_free_fn *free;
|
||||
OSSL_OP_keymgmt_get_params_fn *get_params;
|
||||
OSSL_OP_keymgmt_gettable_params_fn *gettable_params;
|
||||
OSSL_OP_keymgmt_set_params_fn *set_params;
|
||||
OSSL_OP_keymgmt_settable_params_fn *settable_params;
|
||||
|
||||
/* Key object checking */
|
||||
OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
|
||||
OSSL_OP_keymgmt_has_fn *has;
|
||||
OSSL_OP_keymgmt_validate_fn *validate;
|
||||
OSSL_OP_keymgmt_match_fn *match;
|
||||
|
||||
/* Import and export routines */
|
||||
OSSL_OP_keymgmt_import_fn *import;
|
||||
OSSL_OP_keymgmt_import_types_fn *import_types;
|
||||
OSSL_OP_keymgmt_export_fn *export;
|
||||
OSSL_OP_keymgmt_export_types_fn *export_types;
|
||||
OSSL_OP_keymgmt_copy_fn *copy;
|
||||
} /* EVP_KEYMGMT */ ;
|
||||
|
||||
struct evp_keyexch_st {
|
||||
@@ -105,6 +109,8 @@ struct evp_keyexch_st {
|
||||
OSSL_OP_keyexch_dupctx_fn *dupctx;
|
||||
OSSL_OP_keyexch_set_ctx_params_fn *set_ctx_params;
|
||||
OSSL_OP_keyexch_settable_ctx_params_fn *settable_ctx_params;
|
||||
OSSL_OP_keyexch_get_ctx_params_fn *get_ctx_params;
|
||||
OSSL_OP_keyexch_gettable_ctx_params_fn *gettable_ctx_params;
|
||||
} /* EVP_KEYEXCH */;
|
||||
|
||||
struct evp_signature_st {
|
||||
@@ -263,12 +269,10 @@ OSSL_PARAM *evp_pkey_to_param(EVP_PKEY *pkey, size_t *sz);
|
||||
void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx);
|
||||
|
||||
/* OSSL_PROVIDER * is only used to get the library context */
|
||||
const char *evp_first_name(OSSL_PROVIDER *prov, int name_id);
|
||||
const char *evp_first_name(const OSSL_PROVIDER *prov, int name_id);
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number,
|
||||
const char *legacy_name, const char *name);
|
||||
void evp_names_do_all(OSSL_PROVIDER *prov, int number,
|
||||
void (*fn)(const char *name, void *data),
|
||||
void *data);
|
||||
int evp_cipher_cache_constants(EVP_CIPHER *cipher);
|
||||
void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT **keymgmt, const char *propquery);
|
||||
+37
-10
@@ -43,7 +43,7 @@ static void *evp_keyexch_from_dispatch(int name_id,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_KEYEXCH *exchange = NULL;
|
||||
int fncnt = 0, paramfncnt = 0;
|
||||
int fncnt = 0, sparamfncnt = 0, gparamfncnt = 0;
|
||||
|
||||
if ((exchange = evp_keyexch_new(prov)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
@@ -88,28 +88,44 @@ static void *evp_keyexch_from_dispatch(int name_id,
|
||||
break;
|
||||
exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS:
|
||||
if (exchange->get_ctx_params != NULL)
|
||||
break;
|
||||
exchange->get_ctx_params = OSSL_get_OP_keyexch_get_ctx_params(fns);
|
||||
gparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS:
|
||||
if (exchange->gettable_ctx_params != NULL)
|
||||
break;
|
||||
exchange->gettable_ctx_params
|
||||
= OSSL_get_OP_keyexch_gettable_ctx_params(fns);
|
||||
gparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
|
||||
if (exchange->set_ctx_params != NULL)
|
||||
break;
|
||||
exchange->set_ctx_params = OSSL_get_OP_keyexch_set_ctx_params(fns);
|
||||
paramfncnt++;
|
||||
sparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
|
||||
if (exchange->settable_ctx_params != NULL)
|
||||
break;
|
||||
exchange->settable_ctx_params
|
||||
= OSSL_get_OP_keyexch_settable_ctx_params(fns);
|
||||
paramfncnt++;
|
||||
sparamfncnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fncnt != 4 || (paramfncnt != 0 && paramfncnt != 2)) {
|
||||
if (fncnt != 4
|
||||
|| (gparamfncnt != 0 && gparamfncnt != 2)
|
||||
|| (sparamfncnt != 0 && sparamfncnt != 2)) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a complete set of "exchange" functions: init, derive, newctx,
|
||||
* and freectx. The set_ctx_params and settable_ctx_params functions are
|
||||
* optional, but if one of them is present then the other one must also
|
||||
* be present. The dupctx and set_peer functions are optional.
|
||||
* be present. Same goes for get_ctx_params and gettable_ctx_params.
|
||||
* The dupctx and set_peer functions are optional.
|
||||
*/
|
||||
EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
|
||||
EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
@@ -184,10 +200,13 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
if (ctx->engine != NULL || ctx->keytype == NULL)
|
||||
goto legacy;
|
||||
|
||||
/* Ensure that the key is provided. If not, go legacy */
|
||||
/*
|
||||
* Ensure that the key is provided, either natively, or as a cached export.
|
||||
* If not, go legacy
|
||||
*/
|
||||
tmp_keymgmt = ctx->keymgmt;
|
||||
provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
@@ -293,8 +312,12 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
return -2;
|
||||
}
|
||||
|
||||
provkey = evp_keymgmt_util_export_to_provider(peer, ctx->keymgmt);
|
||||
/* If export failed, legacy may be able to pick it up */
|
||||
provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &ctx->keymgmt,
|
||||
ctx->propquery);
|
||||
/*
|
||||
* If making the key provided wasn't possible, legacy may be able to pick
|
||||
* it up
|
||||
*/
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey);
|
||||
@@ -303,6 +326,10 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
#ifdef FIPS_MODE
|
||||
return ret;
|
||||
#else
|
||||
/*
|
||||
* TODO(3.0) investigate the case where the operation is deemed legacy,
|
||||
* but the given peer key is provider only.
|
||||
*/
|
||||
if (ctx->pmeth == NULL
|
||||
|| !(ctx->pmeth->derive != NULL
|
||||
|| ctx->pmeth->encrypt != NULL
|
||||
|
||||
+267
-128
@@ -16,6 +16,18 @@
|
||||
#include "internal/provider.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
/*
|
||||
* match_type() checks if two EVP_KEYMGMT are matching key types. This
|
||||
* function assumes that the caller has made all the necessary NULL checks.
|
||||
*/
|
||||
static int match_type(const EVP_KEYMGMT *keymgmt1, const EVP_KEYMGMT *keymgmt2)
|
||||
{
|
||||
const OSSL_PROVIDER *prov2 = EVP_KEYMGMT_provider(keymgmt2);
|
||||
const char *name2 = evp_first_name(prov2, EVP_KEYMGMT_number(keymgmt2));
|
||||
|
||||
return EVP_KEYMGMT_is_a(keymgmt1, name2);
|
||||
}
|
||||
|
||||
struct import_data_st {
|
||||
EVP_KEYMGMT *keymgmt;
|
||||
void *keydata;
|
||||
@@ -34,161 +46,150 @@ static int try_import(const OSSL_PARAM params[], void *arg)
|
||||
void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
void *keydata = NULL;
|
||||
size_t i, j;
|
||||
struct import_data_st import_data;
|
||||
size_t i = 0;
|
||||
|
||||
/* Export to where? */
|
||||
if (keymgmt == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If we have an unassigned key, give up */
|
||||
if (pk->keymgmt == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If |keymgmt| matches the "origin" |keymgmt|, no more to do */
|
||||
if (pk->keymgmt == keymgmt)
|
||||
return pk->keydata;
|
||||
|
||||
/* If this key is already exported to |keymgmt|, no more to do */
|
||||
i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt);
|
||||
if (i < OSSL_NELEM(pk->operation_cache)
|
||||
&& pk->operation_cache[i].keymgmt != NULL)
|
||||
return pk->operation_cache[i].keydata;
|
||||
|
||||
/* If the "origin" |keymgmt| doesn't support exporting, give up */
|
||||
/*
|
||||
* TODO(3.0) consider an evp_keymgmt_export() return value that indicates
|
||||
* that the method is unsupported.
|
||||
*/
|
||||
if (pk->keymgmt->export == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Check that we have found an empty slot in the export cache */
|
||||
/*
|
||||
* TODO(3.0) Right now, we assume we have ample space. We will have to
|
||||
* think about a cache aging scheme, though, if |i| indexes outside the
|
||||
* array.
|
||||
*/
|
||||
if (!ossl_assert(i < OSSL_NELEM(pk->operation_cache)))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If there is an underlying legacy key and it has changed, invalidate
|
||||
* the cache of provider keys.
|
||||
* Make sure that the type of the keymgmt to export to matches the type
|
||||
* of the "origin"
|
||||
*/
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/*
|
||||
* If there is no dirty counter, this key can't be used with
|
||||
* providers.
|
||||
*/
|
||||
if (pk->ameth->dirty_cnt == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
|
||||
evp_keymgmt_util_clear_pkey_cache(pk);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have exported to this provider already.
|
||||
* If we have, return immediately.
|
||||
*/
|
||||
for (i = 0;
|
||||
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
|
||||
i++) {
|
||||
if (keymgmt == pk->pkeys[i].keymgmt)
|
||||
return pk->pkeys[i].keydata;
|
||||
}
|
||||
if (!ossl_assert(match_type(pk->keymgmt, keymgmt)))
|
||||
return NULL;
|
||||
|
||||
/* Create space to import data into */
|
||||
if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/* There is a legacy key, try to export that one to the provider */
|
||||
/*
|
||||
* We look at the already cached provider keys, and import from the
|
||||
* first that supports it (i.e. use its export function), and export
|
||||
* the imported data to the new provider.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the legacy key doesn't have an export function or the export
|
||||
* function fails, give up
|
||||
*/
|
||||
if (pk->ameth->export_to == NULL
|
||||
|| !pk->ameth->export_to(pk, keydata, keymgmt)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Synchronize the dirty count */
|
||||
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
|
||||
} else {
|
||||
/*
|
||||
* Here, there is no legacy key, so we look at the already cached
|
||||
* provider keys, and import from the first that supports it
|
||||
* (i.e. use its export function), and export the imported data to
|
||||
* the new provider.
|
||||
*/
|
||||
|
||||
/* Setup for the export callback */
|
||||
struct import_data_st import_data;
|
||||
|
||||
import_data.keydata = keydata;
|
||||
import_data.keymgmt = keymgmt;
|
||||
import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
|
||||
|
||||
for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) {
|
||||
EVP_KEYMGMT *exp_keymgmt = pk->pkeys[i].keymgmt;
|
||||
void *exp_keydata = pk->pkeys[i].keydata;
|
||||
|
||||
/*
|
||||
* TODO(3.0) consider an evp_keymgmt_export() return value that
|
||||
* indicates that the method is unsupported.
|
||||
*/
|
||||
if (exp_keymgmt->export == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The export function calls the callback (try_import), which
|
||||
* does the import for us. If successful, we're done.
|
||||
*/
|
||||
if (evp_keymgmt_export(exp_keymgmt, exp_keydata,
|
||||
OSSL_KEYMGMT_SELECT_ALL,
|
||||
&try_import, &import_data))
|
||||
break;
|
||||
|
||||
/* If there was an error, bail out */
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* Setup for the export callback */
|
||||
import_data.keydata = keydata;
|
||||
import_data.keymgmt = keymgmt;
|
||||
import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
|
||||
|
||||
/*
|
||||
* TODO(3.0) Right now, we assume we have ample space. We will
|
||||
* have to think about a cache aging scheme, though, if |i| indexes
|
||||
* outside the array.
|
||||
* The export function calls the callback (try_import), which does the
|
||||
* import for us. If successful, we're done.
|
||||
*/
|
||||
if (!ossl_assert(i < OSSL_NELEM(pk->pkeys)))
|
||||
if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
&try_import, &import_data)) {
|
||||
/* If there was an error, bail out */
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
evp_keymgmt_util_cache_pkey(pk, i, keymgmt, keydata);
|
||||
/* Add the new export to the operation cache */
|
||||
if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, keydata)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keydata;
|
||||
}
|
||||
|
||||
void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk)
|
||||
void evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, end = OSSL_NELEM(pk->operation_cache);
|
||||
|
||||
if (pk != NULL) {
|
||||
for (i = 0;
|
||||
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
|
||||
i++) {
|
||||
EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt;
|
||||
void *keydata = pk->pkeys[i].keydata;
|
||||
for (i = 0; i < end && pk->operation_cache[i].keymgmt != NULL; i++) {
|
||||
EVP_KEYMGMT *keymgmt = pk->operation_cache[i].keymgmt;
|
||||
void *keydata = pk->operation_cache[i].keydata;
|
||||
|
||||
pk->pkeys[i].keymgmt = NULL;
|
||||
pk->pkeys[i].keydata = NULL;
|
||||
pk->operation_cache[i].keymgmt = NULL;
|
||||
pk->operation_cache[i].keydata = NULL;
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
}
|
||||
|
||||
pk->cache.size = 0;
|
||||
pk->cache.bits = 0;
|
||||
pk->cache.security_bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
|
||||
EVP_KEYMGMT *keymgmt, void *keydata)
|
||||
size_t evp_keymgmt_util_find_operation_cache_index(EVP_PKEY *pk,
|
||||
EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
size_t i, end = OSSL_NELEM(pk->operation_cache);
|
||||
|
||||
for (i = 0; i < end && pk->operation_cache[i].keymgmt != NULL; i++) {
|
||||
if (keymgmt == pk->operation_cache[i].keymgmt)
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, size_t index,
|
||||
EVP_KEYMGMT *keymgmt, void *keydata)
|
||||
{
|
||||
if (keydata != NULL) {
|
||||
EVP_KEYMGMT_up_ref(keymgmt);
|
||||
pk->pkeys[index].keydata = keydata;
|
||||
pk->pkeys[index].keymgmt = keymgmt;
|
||||
if (!EVP_KEYMGMT_up_ref(keymgmt))
|
||||
return 0;
|
||||
pk->operation_cache[index].keydata = keydata;
|
||||
pk->operation_cache[index].keymgmt = keymgmt;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache information about the key object. Only needed for the
|
||||
* "original" provider side key.
|
||||
*
|
||||
* This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
|
||||
*/
|
||||
if (index == 0) {
|
||||
int bits = 0;
|
||||
int security_bits = 0;
|
||||
int size = 0;
|
||||
OSSL_PARAM params[4];
|
||||
void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk)
|
||||
{
|
||||
/*
|
||||
* Cache information about the provider "origin" key.
|
||||
*
|
||||
* This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
|
||||
*/
|
||||
if (pk->keymgmt != NULL) {
|
||||
int bits = 0;
|
||||
int security_bits = 0;
|
||||
int size = 0;
|
||||
OSSL_PARAM params[4];
|
||||
|
||||
params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
|
||||
params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
|
||||
&security_bits);
|
||||
params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE,
|
||||
&size);
|
||||
params[3] = OSSL_PARAM_construct_end();
|
||||
if (evp_keymgmt_get_params(keymgmt, keydata, params)) {
|
||||
pk->cache.size = size;
|
||||
pk->cache.bits = bits;
|
||||
pk->cache.security_bits = security_bits;
|
||||
}
|
||||
params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
|
||||
params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
|
||||
&security_bits);
|
||||
params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size);
|
||||
params[3] = OSSL_PARAM_construct_end();
|
||||
if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) {
|
||||
pk->cache.size = size;
|
||||
pk->cache.bits = bits;
|
||||
pk->cache.security_bits = security_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,15 +200,153 @@ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
|
||||
void *keydata = evp_keymgmt_newdata(keymgmt);
|
||||
|
||||
if (keydata != NULL) {
|
||||
if (!evp_keymgmt_import(keymgmt, keydata, selection, params)) {
|
||||
if (!evp_keymgmt_import(keymgmt, keydata, selection, params)
|
||||
|| !EVP_KEYMGMT_up_ref(keymgmt)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
evp_keymgmt_util_clear_pkey_cache(target);
|
||||
evp_keymgmt_util_cache_pkey(target, 0, keymgmt, keydata);
|
||||
evp_keymgmt_util_clear_operation_cache(target);
|
||||
target->keymgmt = keymgmt;
|
||||
target->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(target);
|
||||
}
|
||||
|
||||
return keydata;
|
||||
}
|
||||
|
||||
int evp_keymgmt_util_has(EVP_PKEY *pk, int selection)
|
||||
{
|
||||
/* Check if key is even assigned */
|
||||
if (pk->keymgmt == NULL)
|
||||
return 0;
|
||||
|
||||
return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection);
|
||||
}
|
||||
|
||||
/*
|
||||
* evp_keymgmt_util_match() doesn't just look at the provider side "origin",
|
||||
* but also in the operation cache to see if there's any common keymgmt that
|
||||
* supplies OP_keymgmt_match.
|
||||
*
|
||||
* evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_cmp()
|
||||
* and EVP_PKEY_cmp_parameters() return, i.e.:
|
||||
*
|
||||
* 1 same key
|
||||
* 0 not same key
|
||||
* -1 not same key type
|
||||
* -2 unsupported operation
|
||||
*/
|
||||
int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
|
||||
void *keydata1 = NULL, *keydata2 = NULL;
|
||||
|
||||
if (pk1 == NULL || pk2 == NULL) {
|
||||
if (pk1 == NULL && pk2 == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt1 = pk1->keymgmt;
|
||||
keydata1 = pk1->keydata;
|
||||
keymgmt2 = pk2->keymgmt;
|
||||
keydata2 = pk2->keydata;
|
||||
|
||||
if (keymgmt1 != keymgmt2) {
|
||||
void *tmp_keydata = NULL;
|
||||
|
||||
/* Complex case, where the keymgmt differ */
|
||||
if (keymgmt1 != NULL
|
||||
&& keymgmt2 != NULL
|
||||
&& !match_type(keymgmt1, keymgmt2)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return -1; /* Not the same type */
|
||||
}
|
||||
|
||||
/*
|
||||
* The key types are determined to match, so we try cross export,
|
||||
* but only to keymgmt's that supply a matching function.
|
||||
*/
|
||||
if (keymgmt2 != NULL
|
||||
&& keymgmt2->match != NULL) {
|
||||
tmp_keydata = evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
|
||||
if (tmp_keydata != NULL) {
|
||||
keymgmt1 = keymgmt2;
|
||||
keydata1 = tmp_keydata;
|
||||
}
|
||||
}
|
||||
if (tmp_keydata == NULL
|
||||
&& keymgmt1 != NULL
|
||||
&& keymgmt1->match != NULL) {
|
||||
tmp_keydata = evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
|
||||
if (tmp_keydata != NULL) {
|
||||
keymgmt2 = keymgmt1;
|
||||
keydata2 = tmp_keydata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still don't have matching keymgmt implementations, we give up */
|
||||
if (keymgmt1 != keymgmt2)
|
||||
return -2;
|
||||
|
||||
return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
|
||||
}
|
||||
|
||||
int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
|
||||
{
|
||||
/* Save copies of pointers we want to play with without affecting |to| */
|
||||
EVP_KEYMGMT *to_keymgmt = to->keymgmt;
|
||||
void *to_keydata = to->keydata, *alloc_keydata = NULL;
|
||||
|
||||
/* An unassigned key can't be copied */
|
||||
if (from == NULL || from->keymgmt == NULL)
|
||||
return 0;
|
||||
|
||||
/* If |from| doesn't support copying, we fail */
|
||||
if (from->keymgmt->copy == NULL)
|
||||
return 0;
|
||||
|
||||
/* If |to| doesn't have a provider side "origin" yet, create one */
|
||||
if (to_keymgmt == NULL) {
|
||||
to_keydata = alloc_keydata = evp_keymgmt_newdata(from->keymgmt);
|
||||
if (to_keydata == NULL)
|
||||
return 0;
|
||||
to_keymgmt = from->keymgmt;
|
||||
}
|
||||
|
||||
if (to_keymgmt == from->keymgmt) {
|
||||
/* |to| and |from| have the same keymgmt, just copy and be done */
|
||||
if (!evp_keymgmt_copy(to_keymgmt, to_keydata, from->keydata,
|
||||
selection))
|
||||
return 0;
|
||||
} else if (match_type(to_keymgmt, from->keymgmt)) {
|
||||
struct import_data_st import_data;
|
||||
|
||||
import_data.keymgmt = to_keymgmt;
|
||||
import_data.keydata = to_keydata;
|
||||
import_data.selection = selection;
|
||||
|
||||
if (!evp_keymgmt_export(from->keymgmt, from->keydata, selection,
|
||||
&try_import, &import_data)) {
|
||||
evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (to->keymgmt == NULL
|
||||
&& !EVP_KEYMGMT_up_ref(to_keymgmt)) {
|
||||
evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
|
||||
return 0;
|
||||
}
|
||||
evp_keymgmt_util_clear_operation_cache(to);
|
||||
to->keymgmt = to_keymgmt;
|
||||
to->keydata = to_keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(to);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
int paramfncnt = 0, importfncnt = 0, exportfncnt = 0;
|
||||
int setparamfncnt = 0, getparamfncnt = 0, importfncnt = 0, exportfncnt = 0;
|
||||
|
||||
if ((keymgmt = keymgmt_new()) == NULL) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
@@ -58,17 +58,30 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GET_PARAMS:
|
||||
if (keymgmt->get_params == NULL) {
|
||||
paramfncnt++;
|
||||
getparamfncnt++;
|
||||
keymgmt->get_params = OSSL_get_OP_keymgmt_get_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS:
|
||||
if (keymgmt->gettable_params == NULL) {
|
||||
paramfncnt++;
|
||||
getparamfncnt++;
|
||||
keymgmt->gettable_params =
|
||||
OSSL_get_OP_keymgmt_gettable_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_SET_PARAMS:
|
||||
if (keymgmt->set_params == NULL) {
|
||||
setparamfncnt++;
|
||||
keymgmt->set_params = OSSL_get_OP_keymgmt_set_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS:
|
||||
if (keymgmt->settable_params == NULL) {
|
||||
setparamfncnt++;
|
||||
keymgmt->settable_params =
|
||||
OSSL_get_OP_keymgmt_settable_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
|
||||
if (keymgmt->query_operation_name == NULL)
|
||||
keymgmt->query_operation_name =
|
||||
@@ -82,6 +95,10 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
if (keymgmt->validate == NULL)
|
||||
keymgmt->validate = OSSL_get_OP_keymgmt_validate(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_MATCH:
|
||||
if (keymgmt->match == NULL)
|
||||
keymgmt->match = OSSL_get_OP_keymgmt_match(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_IMPORT:
|
||||
if (keymgmt->import == NULL) {
|
||||
importfncnt++;
|
||||
@@ -119,7 +136,8 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
if (keymgmt->free == NULL
|
||||
|| keymgmt->new == NULL
|
||||
|| keymgmt->has == NULL
|
||||
|| (paramfncnt != 0 && paramfncnt != 2)
|
||||
|| (getparamfncnt != 0 && getparamfncnt != 2)
|
||||
|| (setparamfncnt != 0 && setparamfncnt != 2)
|
||||
|| (importfncnt != 0 && importfncnt != 2)
|
||||
|| (exportfncnt != 0 && exportfncnt != 2)) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
@@ -246,6 +264,21 @@ const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt)
|
||||
return keymgmt->gettable_params();
|
||||
}
|
||||
|
||||
int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
if (keymgmt->set_params == NULL)
|
||||
return 1;
|
||||
return keymgmt->set_params(keydata, params);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
if (keymgmt->settable_params == NULL)
|
||||
return NULL;
|
||||
return keymgmt->settable_params();
|
||||
}
|
||||
|
||||
int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection)
|
||||
{
|
||||
/* This is mandatory, no need to check for its presence */
|
||||
@@ -261,6 +294,16 @@ int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
|
||||
return keymgmt->validate(keydata, selection);
|
||||
}
|
||||
|
||||
int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt,
|
||||
const void *keydata1, const void *keydata2,
|
||||
int selection)
|
||||
{
|
||||
/* We assume no match if the implementation doesn't have a function */
|
||||
if (keymgmt->match == NULL)
|
||||
return 0;
|
||||
return keymgmt->match(keydata1, keydata2, selection);
|
||||
}
|
||||
|
||||
int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
|
||||
int selection, const OSSL_PARAM params[])
|
||||
{
|
||||
@@ -292,3 +335,13 @@ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
|
||||
return NULL;
|
||||
return keymgmt->export_types(selection);
|
||||
}
|
||||
|
||||
int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt,
|
||||
void *keydata_to, const void *keydata_from,
|
||||
int selection)
|
||||
{
|
||||
/* We assume no copy if the implementation doesn't have a function */
|
||||
if (keymgmt->copy == NULL)
|
||||
return 0;
|
||||
return keymgmt->copy(keydata_to, keydata_from, selection);
|
||||
}
|
||||
@@ -64,10 +64,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
if (locpctx->keytype == NULL)
|
||||
goto legacy;
|
||||
|
||||
/* Ensure that the key is provided. If not, go legacy */
|
||||
/*
|
||||
* Ensure that the key is provided, either natively, or as a cached export.
|
||||
* If not, go legacy
|
||||
*/
|
||||
tmp_keymgmt = locpctx->keymgmt;
|
||||
provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx,
|
||||
&tmp_keymgmt, locpctx->propquery);
|
||||
provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx,
|
||||
&tmp_keymgmt, locpctx->propquery);
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
|
||||
+378
-30
@@ -86,12 +86,25 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
|
||||
|
||||
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
{
|
||||
if (to->type == EVP_PKEY_NONE) {
|
||||
if (EVP_PKEY_set_type(to, from->type) == 0)
|
||||
return 0;
|
||||
} else if (to->type != from->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
goto err;
|
||||
/*
|
||||
* TODO: clean up legacy stuff from this function when legacy support
|
||||
* is gone.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Only check that type match this early when both keys are legacy.
|
||||
* If either of them is provided, we let evp_keymgmt_util_copy()
|
||||
* do this check, after having exported either of them that isn't
|
||||
* provided.
|
||||
*/
|
||||
if (to->keymgmt == NULL && from->keymgmt == NULL) {
|
||||
if (to->type == EVP_PKEY_NONE) {
|
||||
if (EVP_PKEY_set_type(to, from->type) == 0)
|
||||
return 0;
|
||||
} else if (to->type != from->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (EVP_PKEY_missing_parameters(from)) {
|
||||
@@ -106,7 +119,56 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (from->ameth && from->ameth->param_copy)
|
||||
/*
|
||||
* If |from| is provided, we upgrade |to| to be provided as well.
|
||||
* This drops the legacy key from |to|.
|
||||
* evp_pkey_upgrade_to_provider() checks if |to| is already provided,
|
||||
* we don't need to do that here.
|
||||
*
|
||||
* TODO(3.0) We should investigate if that's too aggressive and make
|
||||
* this scenario unsupported instead.
|
||||
*/
|
||||
if (from->keymgmt != NULL) {
|
||||
EVP_KEYMGMT *tmp_keymgmt = from->keymgmt;
|
||||
|
||||
/*
|
||||
* The returned pointer is known to be cached, so we don't have to
|
||||
* save it. However, if it's NULL, something went wrong and we can't
|
||||
* copy.
|
||||
*/
|
||||
if (evp_pkey_upgrade_to_provider(to, NULL,
|
||||
&tmp_keymgmt, NULL) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* For purely provided keys, we just call the keymgmt utility */
|
||||
if (to->keymgmt != NULL && from->keymgmt != NULL)
|
||||
return evp_keymgmt_util_copy(to, (EVP_PKEY *)from,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
|
||||
/*
|
||||
* If |to| is provided, we know that |from| is legacy at this point.
|
||||
* Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_copy()
|
||||
* to copy the appropriate data to |to|'s keydata.
|
||||
*/
|
||||
if (to->keymgmt != NULL) {
|
||||
EVP_KEYMGMT *to_keymgmt = to->keymgmt;
|
||||
void *from_keydata =
|
||||
evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
|
||||
NULL);
|
||||
|
||||
if (from_keydata == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return evp_keymgmt_copy(to->keymgmt, to->keydata, from_keydata,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
}
|
||||
|
||||
/* Both keys are legacy */
|
||||
if (from->ameth != NULL && from->ameth->param_copy != NULL)
|
||||
return from->ameth->param_copy(to, from);
|
||||
err:
|
||||
return 0;
|
||||
@@ -114,35 +176,118 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
|
||||
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey != NULL && pkey->ameth && pkey->ameth->param_missing)
|
||||
return pkey->ameth->param_missing(pkey);
|
||||
if (pkey != NULL) {
|
||||
if (pkey->keymgmt != NULL)
|
||||
return !evp_keymgmt_util_has((EVP_PKEY *)pkey,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
|
||||
return pkey->ameth->param_missing(pkey);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called for any mixture of keys except pure legacy pair.
|
||||
* TODO When legacy keys are gone, we replace a call to this functions with
|
||||
* a call to evp_keymgmt_util_match().
|
||||
*/
|
||||
static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
|
||||
int selection)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
|
||||
void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL;
|
||||
|
||||
/* If none of them are provided, this function shouldn't have been called */
|
||||
if (!ossl_assert(a->keymgmt != NULL || b->keymgmt != NULL))
|
||||
return -2;
|
||||
|
||||
/* For purely provided keys, we just call the keymgmt utility */
|
||||
if (a->keymgmt != NULL && b->keymgmt != NULL)
|
||||
return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
|
||||
|
||||
/*
|
||||
* Here, we know that we have a mixture of legacy and provided keys.
|
||||
* Try cross export and compare the resulting key data.
|
||||
*/
|
||||
keymgmt1 = a->keymgmt;
|
||||
keydata1 = a->keydata;
|
||||
keymgmt2 = b->keymgmt;
|
||||
keydata2 = b->keydata;
|
||||
|
||||
if ((keymgmt1 == NULL
|
||||
&& !EVP_KEYMGMT_is_a(keymgmt2, OBJ_nid2sn(a->type)))
|
||||
|| (keymgmt2 == NULL
|
||||
&& !EVP_KEYMGMT_is_a(keymgmt1, OBJ_nid2sn(b->type))))
|
||||
return -1; /* not the same key type */
|
||||
|
||||
if (keymgmt2 != NULL && keymgmt2->match != NULL) {
|
||||
tmp_keydata =
|
||||
evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL);
|
||||
if (tmp_keydata != NULL) {
|
||||
keymgmt1 = keymgmt2;
|
||||
keydata1 = tmp_keydata;
|
||||
}
|
||||
}
|
||||
if (tmp_keydata == NULL && keymgmt1 != NULL && keymgmt1->match != NULL) {
|
||||
tmp_keydata =
|
||||
evp_pkey_export_to_provider((EVP_PKEY *)b, NULL, &keymgmt1, NULL);
|
||||
if (tmp_keydata != NULL) {
|
||||
keymgmt2 = keymgmt1;
|
||||
keydata2 = tmp_keydata;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still don't have matching keymgmt implementations, we give up */
|
||||
if (keymgmt1 != keymgmt2)
|
||||
return -2;
|
||||
|
||||
return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
|
||||
}
|
||||
|
||||
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
/*
|
||||
* TODO: clean up legacy stuff from this function when legacy support
|
||||
* is gone.
|
||||
*/
|
||||
|
||||
if (a->keymgmt != NULL || b->keymgmt != NULL)
|
||||
return evp_pkey_cmp_any(a, b, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
|
||||
/* All legacy keys */
|
||||
if (a->type != b->type)
|
||||
return -1;
|
||||
if (a->ameth && a->ameth->param_cmp)
|
||||
if (a->ameth != NULL && a->ameth->param_cmp != NULL)
|
||||
return a->ameth->param_cmp(a, b);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
/*
|
||||
* TODO: clean up legacy stuff from this function when legacy support
|
||||
* is gone.
|
||||
*/
|
||||
|
||||
if (a->keymgmt != NULL || b->keymgmt != NULL)
|
||||
return evp_pkey_cmp_any(a, b,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
|
||||
| OSSL_KEYMGMT_SELECT_PUBLIC_KEY);
|
||||
|
||||
/* All legacy keys */
|
||||
if (a->type != b->type)
|
||||
return -1;
|
||||
|
||||
if (a->ameth) {
|
||||
if (a->ameth != NULL) {
|
||||
int ret;
|
||||
/* Compare parameters if the algorithm has them */
|
||||
if (a->ameth->param_cmp) {
|
||||
if (a->ameth->param_cmp != NULL) {
|
||||
ret = a->ameth->param_cmp(a, b);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (a->ameth->pub_cmp)
|
||||
if (a->ameth->pub_cmp != NULL)
|
||||
return a->ameth->pub_cmp(a, b);
|
||||
}
|
||||
|
||||
@@ -713,7 +858,7 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
|
||||
static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
|
||||
int arg1, void *arg2)
|
||||
{
|
||||
if (pkey->pkeys[0].keymgmt == NULL)
|
||||
if (pkey->keymgmt == NULL)
|
||||
return 0;
|
||||
switch (op) {
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
@@ -768,9 +913,7 @@ int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
|
||||
mdmandatory,
|
||||
sizeof(mdmandatory));
|
||||
params[2] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->pkeys[0].keymgmt,
|
||||
pkey->pkeys[0].keydata,
|
||||
params))
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
if (mdmandatory[0] != '\0') {
|
||||
OPENSSL_strlcpy(mdname, mdmandatory, mdname_sz);
|
||||
@@ -868,22 +1011,40 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void evp_pkey_free_it(EVP_PKEY *x)
|
||||
#ifndef FIPS_MODE
|
||||
static void evp_pkey_free_legacy(EVP_PKEY *x)
|
||||
{
|
||||
/* internal function; x is never NULL */
|
||||
|
||||
evp_keymgmt_util_clear_pkey_cache(x);
|
||||
|
||||
if (x->ameth && x->ameth->pkey_free) {
|
||||
x->ameth->pkey_free(x);
|
||||
if (x->ameth != NULL) {
|
||||
if (x->ameth->pkey_free != NULL)
|
||||
x->ameth->pkey_free(x);
|
||||
x->pkey.ptr = NULL;
|
||||
x->ameth = NULL;
|
||||
}
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(x->engine);
|
||||
x->engine = NULL;
|
||||
ENGINE_finish(x->pmeth_engine);
|
||||
x->pmeth_engine = NULL;
|
||||
# endif
|
||||
x->type = x->save_type = EVP_PKEY_NONE;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
static void evp_pkey_free_it(EVP_PKEY *x)
|
||||
{
|
||||
/* internal function; x is never NULL */
|
||||
|
||||
evp_keymgmt_util_clear_operation_cache(x);
|
||||
#ifndef FIPS_MODE
|
||||
evp_pkey_free_legacy(x);
|
||||
#endif
|
||||
|
||||
if (x->keymgmt != NULL) {
|
||||
evp_keymgmt_freedata(x->keymgmt, x->keydata);
|
||||
EVP_KEYMGMT_free(x->keymgmt);
|
||||
x->keymgmt = NULL;
|
||||
x->keydata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_PKEY_free(EVP_PKEY *x)
|
||||
@@ -917,8 +1078,9 @@ int EVP_PKEY_size(const EVP_PKEY *pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT **keymgmt, const char *propquery)
|
||||
void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT **keymgmt,
|
||||
const char *propquery)
|
||||
{
|
||||
EVP_KEYMGMT *allocated_keymgmt = NULL;
|
||||
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
||||
@@ -927,11 +1089,23 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
if (pk == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/*
|
||||
* If the legacy key doesn't have an dirty counter or export function,
|
||||
* give up
|
||||
*/
|
||||
if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (keymgmt != NULL) {
|
||||
tmp_keymgmt = *keymgmt;
|
||||
*keymgmt = NULL;
|
||||
}
|
||||
|
||||
/* If no keymgmt was given or found, get a default keymgmt */
|
||||
if (tmp_keymgmt == NULL) {
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
|
||||
|
||||
@@ -941,10 +1115,87 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
}
|
||||
|
||||
if (tmp_keymgmt != NULL)
|
||||
keydata =
|
||||
evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
|
||||
/* If there's still no keymgmt to be had, give up */
|
||||
if (tmp_keymgmt == NULL)
|
||||
goto end;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
size_t i = 0;
|
||||
|
||||
/*
|
||||
* If the legacy "origin" hasn't changed since last time, we try
|
||||
* to find our keymgmt in the operation cache. If it has changed,
|
||||
* |i| remains zero, and we will clear the cache further down.
|
||||
*/
|
||||
if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
|
||||
i = evp_keymgmt_util_find_operation_cache_index(pk, tmp_keymgmt);
|
||||
|
||||
/*
|
||||
* If |tmp_keymgmt| is present in the operation cache, it means
|
||||
* that export doesn't need to be redone. In that case, we take
|
||||
* token copies of the cached pointers, to have token success
|
||||
* values to return.
|
||||
*/
|
||||
if (i < OSSL_NELEM(pk->operation_cache)
|
||||
&& pk->operation_cache[i].keymgmt != NULL) {
|
||||
keydata = pk->operation_cache[i].keydata;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) Right now, we assume we have ample space. We will have
|
||||
* to think about a cache aging scheme, though, if |i| indexes outside
|
||||
* the array.
|
||||
*/
|
||||
if (!ossl_assert(i < OSSL_NELEM(pk->operation_cache)))
|
||||
goto end;
|
||||
|
||||
/* Make sure that the keymgmt key type matches the legacy NID */
|
||||
if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))))
|
||||
goto end;
|
||||
|
||||
if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt)) {
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the dirty counter changed since last time, then clear the
|
||||
* operation cache. In that case, we know that |i| is zero. Just
|
||||
* in case this is a re-export, we increment then decrement the
|
||||
* keymgmt reference counter.
|
||||
*/
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
}
|
||||
if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
|
||||
evp_keymgmt_util_clear_operation_cache(pk);
|
||||
EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */
|
||||
|
||||
/* Add the new export to the operation cache */
|
||||
if (!evp_keymgmt_util_cache_keydata(pk, i, tmp_keymgmt, keydata)) {
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Synchronize the dirty count */
|
||||
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
|
||||
goto end;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
|
||||
|
||||
end:
|
||||
/*
|
||||
* If nothing was exported, |tmp_keymgmt| might point at a freed
|
||||
* EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for
|
||||
@@ -959,3 +1210,100 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT_free(allocated_keymgmt);
|
||||
return keydata;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* This differs from exporting in that it releases the legacy key and assigns
|
||||
* the export keymgmt and keydata to the "origin" provider side key instead
|
||||
* of the operation cache.
|
||||
*/
|
||||
void *evp_pkey_upgrade_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT **keymgmt,
|
||||
const char *propquery)
|
||||
{
|
||||
EVP_KEYMGMT *allocated_keymgmt = NULL;
|
||||
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
||||
void *keydata = NULL;
|
||||
|
||||
if (pk == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If this key is already "upgraded", this function shouldn't have been
|
||||
* called.
|
||||
*/
|
||||
if (!ossl_assert(pk->keymgmt == NULL))
|
||||
return NULL;
|
||||
|
||||
if (keymgmt != NULL) {
|
||||
tmp_keymgmt = *keymgmt;
|
||||
*keymgmt = NULL;
|
||||
}
|
||||
|
||||
/* If the key isn't a legacy one, bail out, but with proper values */
|
||||
if (pk->pkey.ptr == NULL) {
|
||||
tmp_keymgmt = pk->keymgmt;
|
||||
keydata = pk->keydata;
|
||||
} else {
|
||||
/* If the legacy key doesn't have an export function, give up */
|
||||
if (pk->ameth->export_to == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If no keymgmt was given, get a default keymgmt */
|
||||
if (tmp_keymgmt == NULL) {
|
||||
EVP_PKEY_CTX *ctx =
|
||||
EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
|
||||
|
||||
if (ctx != NULL && ctx->keytype != NULL)
|
||||
tmp_keymgmt = allocated_keymgmt =
|
||||
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, propquery);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
}
|
||||
|
||||
/* If we still don't have a keymgmt, give up */
|
||||
if (tmp_keymgmt == NULL)
|
||||
goto end;
|
||||
|
||||
/* Make sure that the keymgmt key type matches the legacy NID */
|
||||
if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))))
|
||||
goto end;
|
||||
|
||||
if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt)
|
||||
|| !EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the operation cache, all the legacy data, as well as the
|
||||
* dirty counters
|
||||
*/
|
||||
evp_pkey_free_legacy(pk);
|
||||
pk->dirty_cnt_copy = 0;
|
||||
|
||||
evp_keymgmt_util_clear_operation_cache(pk);
|
||||
pk->keymgmt = tmp_keymgmt;
|
||||
pk->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(pk);
|
||||
}
|
||||
|
||||
end:
|
||||
/*
|
||||
* If nothing was upgraded, |tmp_keymgmt| might point at a freed
|
||||
* EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for
|
||||
* the caller either way in that case.
|
||||
*/
|
||||
if (keydata == NULL)
|
||||
tmp_keymgmt = NULL;
|
||||
|
||||
if (keymgmt != NULL)
|
||||
*keymgmt = tmp_keymgmt;
|
||||
|
||||
EVP_KEYMGMT_free(allocated_keymgmt);
|
||||
return keydata;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
@@ -224,7 +224,7 @@ static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
type = OSSL_KDF_PARAM_SCRYPT_N;
|
||||
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[0], defs, type,
|
||||
value, strlen(value)))
|
||||
value, strlen(value), NULL))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
||||
@@ -453,7 +453,7 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[0],
|
||||
EVP_MAC_settable_ctx_params(mac),
|
||||
type, value, strlen(value) + 1))
|
||||
type, value, strlen(value) + 1, NULL))
|
||||
return 0;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
|
||||
+10
-10
@@ -28,8 +28,8 @@ int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt = pkey->pkeys[0].keymgmt;
|
||||
key = pkey->pkeys[0].keydata;
|
||||
keymgmt = pkey->keymgmt;
|
||||
key = pkey->keydata;
|
||||
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
@@ -61,8 +61,8 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt = pkey->pkeys[0].keymgmt;
|
||||
key = pkey->pkeys[0].keydata;
|
||||
keymgmt = pkey->keymgmt;
|
||||
key = pkey->keydata;
|
||||
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
@@ -94,8 +94,8 @@ int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt = pkey->pkeys[0].keymgmt;
|
||||
key = pkey->pkeys[0].keydata;
|
||||
keymgmt = pkey->keymgmt;
|
||||
key = pkey->keydata;
|
||||
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
@@ -115,8 +115,8 @@ int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt = pkey->pkeys[0].keymgmt;
|
||||
key = pkey->pkeys[0].keydata;
|
||||
keymgmt = pkey->keymgmt;
|
||||
key = pkey->keydata;
|
||||
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_KEYPAIR);
|
||||
@@ -135,8 +135,8 @@ int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
keymgmt = pkey->pkeys[0].keymgmt;
|
||||
key = pkey->pkeys[0].keydata;
|
||||
keymgmt = pkey->keymgmt;
|
||||
key = pkey->keydata;
|
||||
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_ALL);
|
||||
|
||||
@@ -41,10 +41,13 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
if (ctx->keytype == NULL || ctx->engine != NULL)
|
||||
goto legacy;
|
||||
|
||||
/* Ensure that the key is provided. If not, go legacy */
|
||||
/*
|
||||
* Ensure that the key is provided, either natively, or as a cached export.
|
||||
* If not, go legacy
|
||||
*/
|
||||
tmp_keymgmt = ctx->keymgmt;
|
||||
provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
|
||||
+153
-35
@@ -8,6 +8,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/engine.h>
|
||||
@@ -154,8 +160,7 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
/* If we have an engine, something went wrong somewhere... */
|
||||
if (!ossl_assert(e == NULL))
|
||||
return NULL;
|
||||
name = evp_first_name(pkey->pkeys[0].keymgmt->prov,
|
||||
pkey->pkeys[0].keymgmt->name_id);
|
||||
name = evp_first_name(pkey->keymgmt->prov, pkey->keymgmt->name_id);
|
||||
/*
|
||||
* TODO: I wonder if the EVP_PKEY should have the name and propquery
|
||||
* that were used when building it.... /RL
|
||||
@@ -570,6 +575,12 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
#ifndef FIPS_MODE
|
||||
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
||||
&& ctx->op.kex.exchprovctx != NULL
|
||||
&& ctx->op.kex.exchange != NULL
|
||||
&& ctx->op.kex.exchange->get_ctx_params != NULL)
|
||||
return ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.exchprovctx,
|
||||
params);
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL
|
||||
&& ctx->op.sig.signature != NULL
|
||||
@@ -587,6 +598,10 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
|
||||
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
||||
&& ctx->op.kex.exchange != NULL
|
||||
&& ctx->op.kex.exchange->gettable_ctx_params != NULL)
|
||||
return ctx->op.kex.exchange->gettable_ctx_params();
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.signature != NULL
|
||||
&& ctx->op.sig.signature->gettable_ctx_params != NULL)
|
||||
@@ -618,6 +633,52 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params().
|
||||
*
|
||||
* Return 1 on success, 0 or negative for errors.
|
||||
*
|
||||
* In particular they return -2 if any of the params is not supported.
|
||||
*
|
||||
* They are not available in FIPS_MODE as they depend on
|
||||
* - EVP_PKEY_CTX_{get,set}_params()
|
||||
* - EVP_PKEY_CTX_{gettable,settable}_params()
|
||||
*
|
||||
*/
|
||||
int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if (ctx == NULL || params == NULL)
|
||||
return 0;
|
||||
|
||||
for (p = params; p->key != NULL; p++) {
|
||||
/* Check the ctx actually understands this parameter */
|
||||
if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_settable_params(ctx),
|
||||
p->key) == NULL )
|
||||
return -2;
|
||||
}
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
}
|
||||
|
||||
int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if (ctx == NULL || params == NULL)
|
||||
return 0;
|
||||
|
||||
for (p = params; p->key != NULL; p++ ) {
|
||||
/* Check the ctx actually understands this parameter */
|
||||
if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_gettable_params(ctx),
|
||||
p->key) == NULL )
|
||||
return -2;
|
||||
}
|
||||
|
||||
return EVP_PKEY_CTX_get_params(ctx, params);
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_DH
|
||||
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
|
||||
{
|
||||
@@ -713,42 +774,85 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
||||
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, int p1, void *p2)
|
||||
{
|
||||
switch (cmd) {
|
||||
# ifndef OPENSSL_NO_DH
|
||||
case EVP_PKEY_CTRL_DH_PAD:
|
||||
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
|
||||
if (keytype == EVP_PKEY_DH) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_DH_PAD:
|
||||
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_MD:
|
||||
return EVP_PKEY_CTX_get_signature_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_PADDING:
|
||||
return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_PADDING:
|
||||
return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
|
||||
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
|
||||
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
|
||||
# ifndef OPENSSL_NO_EC
|
||||
if (keytype == EVP_PKEY_EC) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
|
||||
if (p1 == -2) {
|
||||
return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx);
|
||||
} else if (p1 < -1 || p1 > 1) {
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
} else {
|
||||
return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, p1);
|
||||
}
|
||||
case EVP_PKEY_CTRL_EC_KDF_TYPE:
|
||||
if (p1 == -2) {
|
||||
return EVP_PKEY_CTX_get_ecdh_kdf_type(ctx);
|
||||
} else {
|
||||
return EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, p1);
|
||||
}
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_MD:
|
||||
return EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_EC_KDF_MD:
|
||||
return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
|
||||
return EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, p2);
|
||||
case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
|
||||
return EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
|
||||
return EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p2);
|
||||
case EVP_PKEY_CTRL_EC_KDF_UKM:
|
||||
return EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p2, p1);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
if (keytype == -1) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_MD:
|
||||
return EVP_PKEY_CTX_get_signature_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_PADDING:
|
||||
return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_PADDING:
|
||||
return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
|
||||
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
|
||||
return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
|
||||
return EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, p2);
|
||||
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
|
||||
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
case EVP_PKEY_CTRL_CMS_DECRYPT:
|
||||
case EVP_PKEY_CTRL_CMS_ENCRYPT:
|
||||
case EVP_PKEY_CTRL_CMS_DECRYPT:
|
||||
case EVP_PKEY_CTRL_CMS_ENCRYPT:
|
||||
# endif
|
||||
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return 1;
|
||||
ERR_raise(ERR_LIB_EVP,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return 1;
|
||||
ERR_raise(ERR_LIB_EVP,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -817,10 +921,18 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
name = OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST;
|
||||
else if (strcmp(name, "rsa_oaep_label") == 0)
|
||||
name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL;
|
||||
else if (strcmp(name, "rsa_pss_saltlen") == 0)
|
||||
name = OSSL_SIGNATURE_PARAM_PSS_SALTLEN;
|
||||
# ifndef OPENSSL_NO_DH
|
||||
else if (strcmp(name, "dh_pad") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_PAD;
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EC
|
||||
else if (strcmp(name, "ecdh_cofactor_mode") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
|
||||
else if (strcmp(name, "ecdh_kdf_md") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_KDF_TYPE;
|
||||
# endif
|
||||
|
||||
{
|
||||
/*
|
||||
@@ -831,10 +943,16 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
const OSSL_PARAM *settable = EVP_PKEY_CTX_settable_params(ctx);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
int rv = 0;
|
||||
int exists = 0;
|
||||
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[0], settable, name, value,
|
||||
strlen(value)))
|
||||
strlen(value), &exists)) {
|
||||
if (!exists) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_params(ctx, params))
|
||||
rv = 1;
|
||||
OPENSSL_free(params[0].data);
|
||||
|
||||
@@ -342,10 +342,13 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
if (ctx->keytype == NULL)
|
||||
goto legacy;
|
||||
|
||||
/* Ensure that the key is provided. If not, go legacy */
|
||||
/*
|
||||
* Ensure that the key is provided, either natively, or as a cached export.
|
||||
* If not, go legacy
|
||||
*/
|
||||
tmp_keymgmt = ctx->keymgmt;
|
||||
provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
|
||||
@@ -715,6 +715,7 @@ static BIO *HTTP_new_bio(const char *server, const char *server_port,
|
||||
end:
|
||||
return cbio;
|
||||
}
|
||||
#endif /* OPENSSL_NO_SOCK */
|
||||
|
||||
static ASN1_VALUE *BIO_mem_d2i(BIO *mem, const ASN1_ITEM *it)
|
||||
{
|
||||
@@ -744,7 +745,7 @@ static BIO *OSSL_HTTP_REQ_CTX_transfer(OSSL_HTTP_REQ_CTX *rctx)
|
||||
/* BIO_should_retry was true */
|
||||
sending = 0;
|
||||
/* will not actually wait if rctx->max_time == 0 */
|
||||
if (BIO_wait(rctx->rbio, rctx->max_time) <= 0)
|
||||
if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -840,8 +841,13 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
|
||||
if (bio != NULL)
|
||||
cbio = bio;
|
||||
else if ((cbio = HTTP_new_bio(server, port, proxy, proxy_port)) == NULL)
|
||||
else
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if ((cbio = HTTP_new_bio(server, port, proxy, proxy_port)) == NULL)
|
||||
return NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
(void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
|
||||
if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0)
|
||||
@@ -1106,9 +1112,9 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
char *mbuf = OPENSSL_malloc(BUF_SIZE);
|
||||
char *mbufp;
|
||||
int read_len = 0;
|
||||
int rv;
|
||||
int ret = 0;
|
||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||
int rv;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
|
||||
if (bio == NULL || server == NULL || port == NULL
|
||||
@@ -1168,7 +1174,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
|
||||
for (;;) {
|
||||
/* will not actually wait if timeout == 0 */
|
||||
rv = BIO_wait(fbio, max_time);
|
||||
rv = BIO_wait(fbio, max_time, 100 /* milliseconds */);
|
||||
if (rv <= 0) {
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog,
|
||||
rv == 0 ? "timed out" : "failed waiting for data");
|
||||
@@ -1238,4 +1244,3 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
# undef BUF_SIZE
|
||||
}
|
||||
|
||||
#endif /* !defined(OPENSSL_NO_SOCK) */
|
||||
@@ -22,9 +22,7 @@ typedef OCSP_REQ_CTX OSSL_HTTP_REQ_CTX;
|
||||
# define OSSL_HTTP_REQ_CTX_add1_header OCSP_REQ_CTX_add1_header
|
||||
# define OSSL_HTTP_REQ_CTX_i2d OCSP_REQ_CTX_i2d
|
||||
# define OSSL_HTTP_REQ_CTX_nbio OCSP_REQ_CTX_nbio
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
# define OSSL_HTTP_REQ_CTX_sendreq_d2i OCSP_REQ_CTX_nbio_d2i
|
||||
# endif
|
||||
# define OSSL_HTTP_REQ_CTX_sendreq_d2i OCSP_REQ_CTX_nbio_d2i
|
||||
/* functions that are meanwhile unused */
|
||||
# define OSSL_HTTP_REQ_CTX_get0_mem_bio OCSP_REQ_CTX_get0_mem_bio /* undoc'd */
|
||||
# define OSSL_HTTP_REQ_CTX_set_max_response_length OCSP_set_max_response_length
|
||||
|
||||
+29
-15
@@ -227,9 +227,6 @@ size_t CRYPTO_secure_actual_size(void *ptr)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/* END OF PAGE ...
|
||||
|
||||
... START OF PAGE */
|
||||
|
||||
/*
|
||||
* SECURE HEAP IMPLEMENTATION
|
||||
@@ -381,17 +378,33 @@ static int sh_init(size_t size, size_t minsize)
|
||||
|
||||
memset(&sh, 0, sizeof(sh));
|
||||
|
||||
/* make sure size and minsize are powers of 2 */
|
||||
/* make sure size is a powers of 2 */
|
||||
OPENSSL_assert(size > 0);
|
||||
OPENSSL_assert((size & (size - 1)) == 0);
|
||||
OPENSSL_assert((minsize & (minsize - 1)) == 0);
|
||||
if (size <= 0 || (size & (size - 1)) != 0)
|
||||
goto err;
|
||||
if (minsize == 0 || (minsize & (minsize - 1)) != 0)
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
goto err;
|
||||
|
||||
while (minsize < (int)sizeof(SH_LIST))
|
||||
minsize *= 2;
|
||||
if (minsize <= sizeof(SH_LIST)) {
|
||||
OPENSSL_assert(sizeof(SH_LIST) <= 65536);
|
||||
/*
|
||||
* Compute the minimum possible allocation size.
|
||||
* This must be a power of 2 and at least as large as the SH_LIST
|
||||
* structure.
|
||||
*/
|
||||
minsize = sizeof(SH_LIST) - 1;
|
||||
minsize |= minsize >> 1;
|
||||
minsize |= minsize >> 2;
|
||||
if (sizeof(SH_LIST) > 16)
|
||||
minsize |= minsize >> 4;
|
||||
if (sizeof(SH_LIST) > 256)
|
||||
minsize |= minsize >> 8;
|
||||
minsize++;
|
||||
} else {
|
||||
/* make sure minsize is a powers of 2 */
|
||||
OPENSSL_assert((minsize & (minsize - 1)) == 0);
|
||||
if ((minsize & (minsize - 1)) != 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
sh.arena_size = size;
|
||||
sh.minsize = minsize;
|
||||
@@ -437,12 +450,12 @@ static int sh_init(size_t size, size_t minsize)
|
||||
pgsize = PAGE_SIZE;
|
||||
#endif
|
||||
sh.map_size = pgsize + sh.arena_size + pgsize;
|
||||
if (1) {
|
||||
|
||||
#ifdef MAP_ANON
|
||||
sh.map_result = mmap(NULL, sh.map_size,
|
||||
PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
} else {
|
||||
#endif
|
||||
sh.map_result = mmap(NULL, sh.map_size,
|
||||
PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
#else
|
||||
{
|
||||
int fd;
|
||||
|
||||
sh.map_result = MAP_FAILED;
|
||||
@@ -452,6 +465,7 @@ static int sh_init(size_t size, size_t minsize)
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sh.map_result == MAP_FAILED)
|
||||
goto err;
|
||||
sh.arena = (char *)(sh.map_result + pgsize);
|
||||
|
||||
@@ -35,7 +35,6 @@ OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
|
||||
return res;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
|
||||
{
|
||||
*presp = (OCSP_RESPONSE *)
|
||||
@@ -60,6 +59,4 @@ OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req)
|
||||
|
||||
return rv == 1 ? resp : NULL;
|
||||
}
|
||||
# endif /* !defined(OPENSSL_NO_SOCK) */
|
||||
|
||||
#endif /* !defined(OPENSSL_NO_OCSP) */
|
||||
@@ -24,7 +24,7 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
|
||||
const char *value, size_t value_n,
|
||||
/* Output parameters */
|
||||
const OSSL_PARAM **paramdef, int *ishex,
|
||||
size_t *buf_n, BIGNUM **tmpbn)
|
||||
size_t *buf_n, BIGNUM **tmpbn, int *found)
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
@@ -38,6 +38,8 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
|
||||
key += 3;
|
||||
|
||||
p = *paramdef = OSSL_PARAM_locate_const(paramdefs, key);
|
||||
if (found != NULL)
|
||||
*found = p != NULL;
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -163,7 +165,7 @@ static int construct_from_text(OSSL_PARAM *to, const OSSL_PARAM *paramdef,
|
||||
int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to,
|
||||
const OSSL_PARAM *paramdefs,
|
||||
const char *key, const char *value,
|
||||
size_t value_n)
|
||||
size_t value_n, int *found)
|
||||
{
|
||||
const OSSL_PARAM *paramdef = NULL;
|
||||
int ishex = 0;
|
||||
@@ -176,7 +178,7 @@ int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to,
|
||||
return 0;
|
||||
|
||||
if (!prepare_from_text(paramdefs, key, value, value_n,
|
||||
¶mdef, &ishex, &buf_n, &tmpbn))
|
||||
¶mdef, &ishex, &buf_n, &tmpbn, found))
|
||||
return 0;
|
||||
|
||||
if ((buf = OPENSSL_zalloc(buf_n > 0 ? buf_n : 1)) == NULL) {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2020 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
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
package x86_64support;
|
||||
|
||||
# require "x86_64-support.pl";
|
||||
# $ptr_size=&pointer_size($flavour);
|
||||
# $ptr_reg=&pointer_register($flavour,$reg);
|
||||
|
||||
sub ::pointer_size
|
||||
{
|
||||
my($flavour)=@_;
|
||||
my $ptr_size=8; $ptr_size=4 if ($flavour eq "elf32");
|
||||
return $ptr_size;
|
||||
}
|
||||
|
||||
sub ::pointer_register
|
||||
{
|
||||
my($flavour,$reg)=@_;
|
||||
if ($flavour eq "elf32") {
|
||||
if ($reg eq "%rax") {
|
||||
return "%eax";
|
||||
} elsif ($reg eq "%rbx") {
|
||||
return "%ebx";
|
||||
} elsif ($reg eq "%rcx") {
|
||||
return "%ecx";
|
||||
} elsif ($reg eq "%rdx") {
|
||||
return "%edx";
|
||||
} elsif ($reg eq "%rdi") {
|
||||
return "%edi";
|
||||
} elsif ($reg eq "%rsi") {
|
||||
return "%esi";
|
||||
} elsif ($reg eq "%rbp") {
|
||||
return "%ebp";
|
||||
} elsif ($reg eq "%rsp") {
|
||||
return "%esp";
|
||||
} else {
|
||||
return $reg."d";
|
||||
}
|
||||
} else {
|
||||
return $reg;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -83,6 +83,10 @@ my $PTR=" PTR";
|
||||
my $nasmref=2.03;
|
||||
my $nasm=0;
|
||||
|
||||
# GNU as indicator, as opposed to $gas, which indicates acceptable
|
||||
# syntax
|
||||
my $gnuas=0;
|
||||
|
||||
if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
|
||||
$prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
|
||||
$prefix =~ s|\R$||; # Better chomp
|
||||
@@ -100,6 +104,17 @@ elsif (!$gas)
|
||||
$elf=0;
|
||||
$decor="\$L\$";
|
||||
}
|
||||
# Find out if we're using GNU as
|
||||
elsif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
=~ /GNU assembler version ([2-9]\.[0-9]+)/)
|
||||
{
|
||||
$gnuas=1;
|
||||
}
|
||||
elsif (`$ENV{CC} --version 2>/dev/null`
|
||||
=~ /clang .*/)
|
||||
{
|
||||
$gnuas=1;
|
||||
}
|
||||
|
||||
my $cet_property;
|
||||
if ($flavour =~ /elf/) {
|
||||
@@ -108,14 +123,21 @@ if ($flavour =~ /elf/) {
|
||||
# with Intel CET support in order for linker to mark output with
|
||||
# Intel CET support.
|
||||
my $p2align=3; $p2align=2 if ($flavour eq "elf32");
|
||||
my $section='.note.gnu.property, #alloc';
|
||||
$section='".note.gnu.property", "a"' if $gnuas;
|
||||
$cet_property = <<_____;
|
||||
.section ".note.gnu.property", "a"
|
||||
.section $section
|
||||
.p2align $p2align
|
||||
.long 1f - 0f
|
||||
.long 4f - 1f
|
||||
.long 5
|
||||
0:
|
||||
.asciz "GNU"
|
||||
# "GNU" encoded with .byte, since .asciz isn't supported
|
||||
# on Solaris.
|
||||
.byte 0x47
|
||||
.byte 0x4e
|
||||
.byte 0x55
|
||||
.byte 0
|
||||
1:
|
||||
.p2align $p2align
|
||||
.long 0xc0000002
|
||||
|
||||
@@ -562,12 +562,9 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||
int ossl_property_parse_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
static const char *const predefined_names[] = {
|
||||
"default", /* Being provided by the default built-in provider */
|
||||
"legacy", /* Provided by the legacy provider */
|
||||
"provider", /* Name of provider (default, fips) */
|
||||
"provider", /* Name of provider (default, legacy, fips) */
|
||||
"version", /* Version number of this provider */
|
||||
"fips", /* FIPS supporting provider */
|
||||
"engine", /* An old style engine masquerading as a provider */
|
||||
"fips", /* FIPS validated or FIPS supporting algorithm */
|
||||
"format", /* output format for serializers */
|
||||
"type", /* output type for serializers */
|
||||
};
|
||||
|
||||
+47
-32
@@ -115,6 +115,9 @@ static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx,
|
||||
unsigned int flags,
|
||||
RAND_DRBG *parent);
|
||||
|
||||
static int rand_drbg_set(RAND_DRBG *drbg, int type, unsigned int flags);
|
||||
static int rand_drbg_init_method(RAND_DRBG *drbg);
|
||||
|
||||
static int is_ctr(int type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -341,8 +344,11 @@ void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg)
|
||||
*/
|
||||
int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
{
|
||||
int ret = 1;
|
||||
return rand_drbg_set(drbg, type, flags) && rand_drbg_init_method(drbg);
|
||||
}
|
||||
|
||||
static int rand_drbg_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
{
|
||||
if (type == 0 && flags == 0) {
|
||||
type = rand_drbg_type[RAND_DRBG_TYPE_MASTER];
|
||||
flags = rand_drbg_flags[RAND_DRBG_TYPE_MASTER];
|
||||
@@ -350,7 +356,8 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
|
||||
/* If set is called multiple times - clear the old one */
|
||||
if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) {
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
if (drbg->meth != NULL)
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
rand_pool_free(drbg->adin_pool);
|
||||
drbg->adin_pool = NULL;
|
||||
}
|
||||
@@ -358,29 +365,43 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
drbg->state = DRBG_UNINITIALISED;
|
||||
drbg->flags = flags;
|
||||
drbg->type = type;
|
||||
drbg->meth = NULL;
|
||||
|
||||
if (type == 0) {
|
||||
/* Uninitialized; that's okay. */
|
||||
drbg->meth = NULL;
|
||||
if (type == 0 || is_ctr(type) || is_digest(type))
|
||||
return 1;
|
||||
} else if (is_ctr(type)) {
|
||||
|
||||
drbg->type = 0;
|
||||
drbg->flags = 0;
|
||||
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rand_drbg_init_method(RAND_DRBG *drbg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (drbg->meth != NULL)
|
||||
return 1;
|
||||
|
||||
if (is_ctr(drbg->type)) {
|
||||
ret = drbg_ctr_init(drbg);
|
||||
} else if (is_digest(type)) {
|
||||
if (flags & RAND_DRBG_FLAG_HMAC)
|
||||
} else if (is_digest(drbg->type)) {
|
||||
if (drbg->flags & RAND_DRBG_FLAG_HMAC)
|
||||
ret = drbg_hmac_init(drbg);
|
||||
else
|
||||
ret = drbg_hash_init(drbg);
|
||||
} else {
|
||||
/* other cases should already be excluded */
|
||||
RANDerr(RAND_F_RAND_DRBG_INIT_METHOD, ERR_R_INTERNAL_ERROR);
|
||||
drbg->type = 0;
|
||||
drbg->flags = 0;
|
||||
drbg->meth = NULL;
|
||||
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
drbg->state = DRBG_ERROR;
|
||||
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
|
||||
RANDerr(RAND_F_RAND_DRBG_INIT_METHOD, RAND_R_ERROR_INITIALISING_DRBG);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -554,9 +575,17 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||
{
|
||||
unsigned char *nonce = NULL, *entropy = NULL;
|
||||
size_t noncelen = 0, entropylen = 0;
|
||||
size_t min_entropy = drbg->strength;
|
||||
size_t min_entropylen = drbg->min_entropylen;
|
||||
size_t max_entropylen = drbg->max_entropylen;
|
||||
size_t min_entropy, min_entropylen, max_entropylen;
|
||||
|
||||
if (drbg->meth == NULL && !rand_drbg_init_method(drbg)) {
|
||||
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
|
||||
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
|
||||
goto end;
|
||||
}
|
||||
|
||||
min_entropy = drbg->strength;
|
||||
min_entropylen = drbg->min_entropylen;
|
||||
max_entropylen = drbg->max_entropylen;
|
||||
|
||||
if (perslen > drbg->max_perslen) {
|
||||
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
|
||||
@@ -564,12 +593,6 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (drbg->meth == NULL) {
|
||||
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
|
||||
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (drbg->state != DRBG_UNINITIALISED) {
|
||||
if (drbg->state == DRBG_ERROR)
|
||||
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_IN_ERROR_STATE);
|
||||
@@ -648,19 +671,11 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
|
||||
{
|
||||
int index = -1, type, flags;
|
||||
if (drbg->meth == NULL) {
|
||||
drbg->state = DRBG_ERROR;
|
||||
RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
|
||||
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
|
||||
return 0;
|
||||
if (drbg->meth != NULL) {
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
drbg->meth = NULL;
|
||||
}
|
||||
|
||||
/* Clear the entire drbg->ctr struct, then reset some important
|
||||
* members of the drbg->ctr struct (e.g. keysize, df_ks) to their
|
||||
* initial values.
|
||||
*/
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
|
||||
/* The reset uses the default values for type and flags */
|
||||
if (drbg->flags & RAND_DRBG_FLAG_MASTER)
|
||||
index = RAND_DRBG_TYPE_MASTER;
|
||||
@@ -676,7 +691,7 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
|
||||
flags = drbg->flags;
|
||||
type = drbg->type;
|
||||
}
|
||||
return RAND_DRBG_set(drbg, type, flags);
|
||||
return rand_drbg_set(drbg, type, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \
|
||||
$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_aid.c rsa_pk1.c \
|
||||
rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \
|
||||
rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/rsa.h"
|
||||
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_OID 0x06
|
||||
|
||||
/*
|
||||
* -- RFC 2313
|
||||
* pkcs-1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 1
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* -- RFC 3279
|
||||
* md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
|
||||
* md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
|
||||
* sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_PKCS1(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0b, \
|
||||
ASN1_OID, 0x09, 1 * 40 + 2, 134, 72, 134, 247, 13, 1, 1, n \
|
||||
}
|
||||
#ifndef FIPS_MODE
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(md2, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(md5, 4);
|
||||
#endif
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha1, 5);
|
||||
|
||||
/*
|
||||
* -- RFC 4055
|
||||
* sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 }
|
||||
* sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
|
||||
* sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
|
||||
* sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
|
||||
*/
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha224, 14);
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha256, 11);
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha384, 12);
|
||||
ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha512, 13);
|
||||
|
||||
/*
|
||||
* -- https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
|
||||
*
|
||||
* sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
|
||||
*
|
||||
* id-rsassa-pkcs1-v1_5-with-sha3-224 ::= { sigAlgs 13 }
|
||||
* id-rsassa-pkcs1-v1_5-with-sha3-256 ::= { sigAlgs 14 }
|
||||
* id-rsassa-pkcs1-v1_5-with-sha3-384 ::= { sigAlgs 15 }
|
||||
* id-rsassa-pkcs1-v1_5-with-sha3-512 ::= { sigAlgs 16 }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0c, \
|
||||
ASN1_OID, 0x0a, 1 * 40 + 2, 16, 134, 72, 1, 101, 3, 4, 3, n \
|
||||
}
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 13);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 14);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 15);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 16);
|
||||
|
||||
#define MD_CASE(name) \
|
||||
case NID_##name: \
|
||||
*len = sizeof(algorithmidentifier_##name##_der); \
|
||||
return algorithmidentifier_##name##_der
|
||||
|
||||
const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (md_nid) {
|
||||
#ifndef FIPS_MODE
|
||||
MD_CASE(md2);
|
||||
MD_CASE(md5);
|
||||
#endif
|
||||
MD_CASE(sha1);
|
||||
MD_CASE(sha224);
|
||||
MD_CASE(sha256);
|
||||
MD_CASE(sha384);
|
||||
MD_CASE(sha512);
|
||||
MD_CASE(sha3_224);
|
||||
MD_CASE(sha3_256);
|
||||
MD_CASE(sha3_384);
|
||||
MD_CASE(sha3_512);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1114,7 +1114,13 @@ static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
numexps = sk_BIGNUM_const_num(exps);
|
||||
numcoeffs = sk_BIGNUM_const_num(coeffs);
|
||||
|
||||
if (numprimes < 2 || numexps < 2 || numcoeffs < 1)
|
||||
/*
|
||||
* It's permisssible to have zero primes, i.e. no CRT params.
|
||||
* Otherwise, there must be at least two, as many exponents,
|
||||
* and one coefficient less.
|
||||
*/
|
||||
if (numprimes != 0
|
||||
&& (numprimes < 2 || numexps < 2 || numcoeffs < 1))
|
||||
goto err;
|
||||
|
||||
/* assert that an OSSL_PARAM_BLD has enough space. */
|
||||
|
||||
+87
-11
@@ -17,10 +17,12 @@
|
||||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "rsa_local.h"
|
||||
|
||||
static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
BN_GENCB *cb);
|
||||
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg);
|
||||
static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
|
||||
BIGNUM *e_value, BN_GENCB *cb, int pairwise_test);
|
||||
|
||||
/*
|
||||
* NB: this wrapper would normally be placed in rsa_lib.c and the static
|
||||
@@ -59,19 +61,21 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
|
||||
return 0;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
return rsa_builtin_keygen(rsa, bits, primes, e_value, cb);
|
||||
return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0);
|
||||
}
|
||||
|
||||
static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
BN_GENCB *cb)
|
||||
static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
|
||||
BIGNUM *e_value, BN_GENCB *cb, int pairwise_test)
|
||||
{
|
||||
int ok = -1;
|
||||
#ifdef FIPS_MODE
|
||||
if (primes != 2)
|
||||
return 0;
|
||||
return rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
|
||||
ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
|
||||
pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */
|
||||
#else
|
||||
BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime;
|
||||
int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
|
||||
int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
|
||||
int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0;
|
||||
RSA_PRIME_INFO *pinfo = NULL;
|
||||
STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL;
|
||||
@@ -81,13 +85,13 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
|
||||
if (bits < RSA_MIN_MODULUS_BITS) {
|
||||
ok = 0; /* we set our own err */
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
|
||||
RSAerr(0, RSA_R_KEY_SIZE_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) {
|
||||
ok = 0; /* we set our own err */
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID);
|
||||
RSAerr(0, RSA_R_KEY_PRIME_NUM_INVALID);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -392,11 +396,83 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
ok = 1;
|
||||
err:
|
||||
if (ok == -1) {
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
|
||||
RSAerr(0, ERR_LIB_BN);
|
||||
ok = 0;
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
if (pairwise_test && ok > 0) {
|
||||
OSSL_CALLBACK *stcb = NULL;
|
||||
void *stcbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
|
||||
ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
|
||||
if (!ok) {
|
||||
/* Clear intermediate results */
|
||||
BN_clear_free(rsa->d);
|
||||
BN_clear_free(rsa->p);
|
||||
BN_clear_free(rsa->q);
|
||||
BN_clear_free(rsa->dmp1);
|
||||
BN_clear_free(rsa->dmq1);
|
||||
BN_clear_free(rsa->iqmp);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* For RSA key generation it is not known whether the key pair will be used
|
||||
* for key transport or signatures. FIPS 140-2 IG 9.9 states that in this case
|
||||
* either a signature verification OR an encryption operation may be used to
|
||||
* perform the pairwise consistency check. The simpler encrypt/decrypt operation
|
||||
* has been chosen for this case.
|
||||
*/
|
||||
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int ciphertxt_len;
|
||||
unsigned char *ciphertxt = NULL;
|
||||
const unsigned char plaintxt[16] = {0};
|
||||
unsigned char decoded[256];
|
||||
unsigned int decoded_len;
|
||||
unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len);
|
||||
int padding = RSA_PKCS1_PADDING;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
goto err;
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1);
|
||||
|
||||
ciphertxt_len = RSA_size(rsa);
|
||||
ciphertxt = OPENSSL_zalloc(ciphertxt_len);
|
||||
if (ciphertxt == NULL)
|
||||
goto err;
|
||||
|
||||
ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa,
|
||||
padding);
|
||||
if (ciphertxt_len <= 0)
|
||||
goto err;
|
||||
if (ciphertxt_len == plaintxt_len
|
||||
&& memcmp(decoded, plaintxt, plaintxt_len) == 0)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt);
|
||||
|
||||
decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa,
|
||||
padding);
|
||||
if (decoded_len != plaintxt_len
|
||||
|| memcmp(decoded, plaintxt, decoded_len) != 0)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
OPENSSL_free(ciphertxt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+94
-23
@@ -774,6 +774,10 @@ int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
|
||||
if (r == NULL)
|
||||
return 0;
|
||||
|
||||
/* If |p| is NULL, there are no CRT parameters */
|
||||
if (RSA_get0_p(r) == NULL)
|
||||
return 1;
|
||||
|
||||
sk_BIGNUM_const_push(primes, RSA_get0_p(r));
|
||||
sk_BIGNUM_const_push(primes, RSA_get0_q(r));
|
||||
sk_BIGNUM_const_push(exps, RSA_get0_dmp1(r));
|
||||
@@ -811,12 +815,14 @@ int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
|
||||
return -1;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
|| ctx->op.ciph.ciphprovctx == NULL)
|
||||
if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
|| ctx->op.ciph.ciphprovctx == NULL)
|
||||
&& (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
|| ctx->op.sig.sigprovctx == NULL))
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING,
|
||||
pad_mode, NULL);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, &pad_mode);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, &pad_mode);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, pad_params);
|
||||
@@ -839,12 +845,14 @@ int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
|
||||
return -1;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
|| ctx->op.ciph.ciphprovctx == NULL)
|
||||
if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
|| ctx->op.ciph.ciphprovctx == NULL)
|
||||
&& (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
|| ctx->op.sig.sigprovctx == NULL))
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0,
|
||||
pad_mode);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, pad_mode);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, pad_mode);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
|
||||
@@ -1020,20 +1028,20 @@ int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
* Cast away the const. This is
|
||||
* read only so should be safe
|
||||
*/
|
||||
(char *)mdname, 0);
|
||||
if (mdprops != NULL) {
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(
|
||||
OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)mdprops, 0);
|
||||
*p++ =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_PROPERTIES,
|
||||
/*
|
||||
* Cast away the const. This is
|
||||
* read only so should be safe
|
||||
*/
|
||||
(char *)mdprops, 0);
|
||||
}
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
@@ -1059,7 +1067,7 @@ int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
|
||||
name, namelen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
@@ -1127,12 +1135,12 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
|
||||
(void *)label);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(void *)label,
|
||||
(size_t)llen);
|
||||
/*
|
||||
* Cast away the const. This is
|
||||
* read only so should be safe
|
||||
*/
|
||||
(void *)label,
|
||||
(size_t)llen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_PKEY_CTX_set_params(ctx, rsa_params))
|
||||
@@ -1177,4 +1185,67 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label)
|
||||
|
||||
return (int)labellen;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
|
||||
{
|
||||
OSSL_PARAM pad_params[2], *p = pad_params;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* If key type not RSA or RSA-PSS return error */
|
||||
if (ctx->pmeth != NULL
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return -1;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
|| ctx->op.sig.sigprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
|
||||
saltlen, NULL);
|
||||
|
||||
*p++ =
|
||||
OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, &saltlen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, pad_params);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
|
||||
{
|
||||
OSSL_PARAM pad_params[2], *p = pad_params;
|
||||
|
||||
if (ctx == NULL || saltlen == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* If key type not RSA or RSA-PSS return error */
|
||||
if (ctx->pmeth != NULL
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA
|
||||
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
return -1;
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
|| ctx->op.sig.sigprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, -1,
|
||||
EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN,
|
||||
0, saltlen);
|
||||
|
||||
*p++ =
|
||||
OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, saltlen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -122,10 +122,6 @@ struct rsa_meth_st {
|
||||
BIGNUM *e, BN_GENCB *cb);
|
||||
};
|
||||
|
||||
extern int int_rsa_verify(int dtype, const unsigned char *m,
|
||||
unsigned int m_len, unsigned char *rm,
|
||||
size_t *prm_len, const unsigned char *sigbuf,
|
||||
size_t siglen, RSA *rsa);
|
||||
/* Macros to test if a pkey or ctx is for a PSS key */
|
||||
#define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS)
|
||||
#define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/cms.h>
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/rsa.h"
|
||||
#include "rsa_local.h"
|
||||
|
||||
/* RSA pkey context structure */
|
||||
|
||||
+33
-7
@@ -17,13 +17,20 @@
|
||||
#ifndef OPENSSL_NO_MD2
|
||||
# include <openssl/md2.h> /* uses MD2_DIGEST_LENGTH */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h> /* uses MD4_DIGEST_LENGTH */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
# include <openssl/md5.h> /* uses MD5_DIGEST_LENGTH */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MDC2
|
||||
# include <openssl/mdc2.h> /* uses MDC2_DIGEST_LENGTH */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RMD160
|
||||
# include <openssl/ripemd.h> /* uses RIPEMD160_DIGEST_LENGTH */
|
||||
#endif
|
||||
#include <openssl/sha.h> /* uses SHA???_DIGEST_LENGTH */
|
||||
#include "crypto/rsa.h"
|
||||
#include "rsa_local.h"
|
||||
|
||||
/*
|
||||
@@ -70,7 +77,7 @@ static const unsigned char digestinfo_##name##_der[] = { \
|
||||
ASN1_OCTET_STRING, sz \
|
||||
};
|
||||
|
||||
/* MD2 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */
|
||||
/* MD2, MD4 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */
|
||||
#define ENCODE_DIGESTINFO_MD(name, n, sz) \
|
||||
static const unsigned char digestinfo_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x10 + sz, \
|
||||
@@ -84,6 +91,9 @@ static const unsigned char digestinfo_##name##_der[] = { \
|
||||
# ifndef OPENSSL_NO_MD2
|
||||
ENCODE_DIGESTINFO_MD(md2, 0x02, MD2_DIGEST_LENGTH)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
ENCODE_DIGESTINFO_MD(md4, 0x03, MD4_DIGEST_LENGTH)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MD5
|
||||
ENCODE_DIGESTINFO_MD(md5, 0x05, MD5_DIGEST_LENGTH)
|
||||
# endif
|
||||
@@ -97,6 +107,18 @@ static const unsigned char digestinfo_mdc2_der[] = {
|
||||
ASN1_OCTET_STRING, MDC2_DIGEST_LENGTH
|
||||
};
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_RMD160
|
||||
/* RIPEMD160 (1 3 36 3 3 1 2) */
|
||||
static const unsigned char digestinfo_ripemd160_der[] = {
|
||||
ASN1_SEQUENCE, 0x0c + RIPEMD160_DIGEST_LENGTH,
|
||||
ASN1_SEQUENCE, 0x08,
|
||||
ASN1_OID, 0x04, 1 * 40 + 3, 36, 3, 3, 1, 2,
|
||||
ASN1_NULL, 0x00,
|
||||
ASN1_OCTET_STRING, RIPEMD160_DIGEST_LENGTH
|
||||
};
|
||||
# endif
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
/* SHA-1 (1 3 14 3 2 26) */
|
||||
static const unsigned char digestinfo_sha1_der[] = {
|
||||
ASN1_SEQUENCE, 0x0d + SHA_DIGEST_LENGTH,
|
||||
@@ -106,8 +128,6 @@ static const unsigned char digestinfo_sha1_der[] = {
|
||||
ASN1_OCTET_STRING, SHA_DIGEST_LENGTH
|
||||
};
|
||||
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ENCODE_DIGESTINFO_SHA(sha256, 0x01, SHA256_DIGEST_LENGTH)
|
||||
ENCODE_DIGESTINFO_SHA(sha384, 0x02, SHA384_DIGEST_LENGTH)
|
||||
ENCODE_DIGESTINFO_SHA(sha512, 0x03, SHA512_DIGEST_LENGTH)
|
||||
@@ -124,9 +144,9 @@ ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH)
|
||||
*len = sizeof(digestinfo_##name##_der); \
|
||||
return digestinfo_##name##_der;
|
||||
|
||||
static const unsigned char *digestinfo_encoding(int nid, size_t *len)
|
||||
const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (nid) {
|
||||
switch (md_nid) {
|
||||
#ifndef FIPS_MODE
|
||||
# ifndef OPENSSL_NO_MDC2
|
||||
MD_CASE(mdc2)
|
||||
@@ -134,11 +154,17 @@ static const unsigned char *digestinfo_encoding(int nid, size_t *len)
|
||||
# ifndef OPENSSL_NO_MD2
|
||||
MD_CASE(md2)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
MD_CASE(md4)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MD5
|
||||
MD_CASE(md5)
|
||||
# endif
|
||||
MD_CASE(sha1)
|
||||
# ifndef OPENSSL_NO_RMD160
|
||||
MD_CASE(ripemd160)
|
||||
# endif
|
||||
#endif /* FIPS_MODE */
|
||||
MD_CASE(sha1)
|
||||
MD_CASE(sha224)
|
||||
MD_CASE(sha256)
|
||||
MD_CASE(sha384)
|
||||
@@ -177,7 +203,7 @@ static int encode_pkcs1(unsigned char **out, size_t *out_len, int type,
|
||||
RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE);
|
||||
return 0;
|
||||
}
|
||||
di_prefix = digestinfo_encoding(type, &di_prefix_len);
|
||||
di_prefix = rsa_digestinfo_encoding(type, &di_prefix_len);
|
||||
if (di_prefix == NULL) {
|
||||
RSAerr(RSA_F_ENCODE_PKCS1,
|
||||
RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
|
||||
|
||||
+107
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
#include <openssl/self_test.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
typedef struct self_test_cb_st
|
||||
@@ -16,6 +18,19 @@ typedef struct self_test_cb_st
|
||||
void *cbarg;
|
||||
} SELF_TEST_CB;
|
||||
|
||||
struct ossl_self_test_st
|
||||
{
|
||||
/* local state variables */
|
||||
const char *phase;
|
||||
const char *type;
|
||||
const char *desc;
|
||||
OSSL_CALLBACK *cb;
|
||||
|
||||
/* callback related variables used to pass the state back to the user */
|
||||
OSSL_PARAM params[4];
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
static void *self_test_set_callback_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
SELF_TEST_CB *stcb;
|
||||
@@ -40,6 +55,7 @@ static SELF_TEST_CB *get_self_test_callback(OPENSSL_CTX *libctx)
|
||||
&self_test_set_callback_method);
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
|
||||
void *cbarg)
|
||||
{
|
||||
@@ -50,6 +66,8 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
|
||||
stcb->cbarg = cbarg;
|
||||
}
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
|
||||
void **cbarg)
|
||||
{
|
||||
@@ -60,3 +78,91 @@ void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
|
||||
if (cbarg != NULL)
|
||||
*cbarg = (stcb != NULL ? stcb->cbarg : NULL);
|
||||
}
|
||||
|
||||
static void self_test_setparams(OSSL_SELF_TEST *st)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
if (st->cb != NULL) {
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
|
||||
(char *)st->phase, 0);
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
|
||||
(char *)st->type, 0);
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
|
||||
(char *)st->desc, 0);
|
||||
}
|
||||
st->params[n++] = OSSL_PARAM_construct_end();
|
||||
}
|
||||
|
||||
OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
ret->cb = cb;
|
||||
ret->cb_arg = cbarg;
|
||||
ret->phase = "";
|
||||
ret->type = "";
|
||||
ret->desc = "";
|
||||
self_test_setparams(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st)
|
||||
{
|
||||
OPENSSL_free(st);
|
||||
}
|
||||
|
||||
/* Can be used during application testing to log that a test has started. */
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase = OSSL_SELF_TEST_PHASE_START;
|
||||
st->type = type;
|
||||
st->desc = desc;
|
||||
self_test_setparams(st);
|
||||
(void)st->cb(st->params, st->cb_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Can be used during application testing to log that a test has either
|
||||
* passed or failed.
|
||||
*/
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase =
|
||||
(ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
|
||||
self_test_setparams(st);
|
||||
(void)st->cb(st->params, st->cb_arg);
|
||||
|
||||
st->phase = OSSL_SELF_TEST_PHASE_NONE;
|
||||
st->type = OSSL_SELF_TEST_TYPE_NONE;
|
||||
st->desc = OSSL_SELF_TEST_DESC_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for failure testing.
|
||||
*
|
||||
* Call the applications SELF_TEST_cb() if it exists.
|
||||
* If the application callback decides to return 0 then the first byte of 'bytes'
|
||||
* is modified (corrupted). This is used to modify output signatures or
|
||||
* ciphertext before they are verified or decrypted.
|
||||
*/
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
|
||||
self_test_setparams(st);
|
||||
if (!st->cb(st->params, st->cb_arg))
|
||||
bytes[0] ^= 1;
|
||||
}
|
||||
}
|
||||
@@ -267,8 +267,8 @@ static int serializer_write_cb(const OSSL_PARAM params[], void *arg)
|
||||
static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
|
||||
{
|
||||
const EVP_PKEY *pkey = ctx->object;
|
||||
void *keydata = pkey->pkeys[0].keydata;
|
||||
EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt;
|
||||
void *keydata = pkey->keydata;
|
||||
EVP_KEYMGMT *keymgmt = pkey->keymgmt;
|
||||
|
||||
/*
|
||||
* OSSL_SERIALIZER_CTX_new() creates a context, even when the
|
||||
@@ -306,7 +306,7 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
|
||||
{
|
||||
OSSL_SERIALIZER_CTX *ctx = NULL;
|
||||
OSSL_SERIALIZER *ser = NULL;
|
||||
EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt;
|
||||
EVP_KEYMGMT *keymgmt = pkey->keymgmt;
|
||||
int selection = OSSL_KEYMGMT_SELECT_ALL;
|
||||
|
||||
if (!ossl_assert(pkey != NULL && propquery != NULL)) {
|
||||
|
||||
@@ -50,6 +50,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
push(@INC,"${dir}","${dir}../../perlasm");
|
||||
require "x86_64-support.pl";
|
||||
|
||||
$ptr_size=&pointer_size($flavour);
|
||||
|
||||
$avx=0;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
@@ -89,6 +94,7 @@ $inp="%rsi"; # 2nd arg
|
||||
$num="%edx";
|
||||
@ptr=map("%r$_",(8..11));
|
||||
$Tbl="%rbp";
|
||||
$inp_elm_size=2*$ptr_size;
|
||||
|
||||
@V=($A,$B,$C,$D,$E)=map("%xmm$_",(0..4));
|
||||
($t0,$t1,$t2,$t3,$tx)=map("%xmm$_",(5..9));
|
||||
@@ -409,9 +415,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -488,7 +497,7 @@ $code.=<<___;
|
||||
|
||||
mov `$REG_SZ*17+8`(%rsp),$num
|
||||
lea $REG_SZ($ctx),$ctx
|
||||
lea `16*$REG_SZ/4`($inp),$inp
|
||||
lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande
|
||||
|
||||
@@ -566,9 +575,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<2;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -751,7 +763,7 @@ $code.=<<___;
|
||||
movq $E0,0x80-0x40($ctx) # e1.e0
|
||||
|
||||
lea `$REG_SZ/2`($ctx),$ctx
|
||||
lea `16*2`($inp),$inp
|
||||
lea `$inp_elm_size*2`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande_shaext
|
||||
|
||||
@@ -1071,9 +1083,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -1144,7 +1159,7 @@ $code.=<<___;
|
||||
|
||||
mov `$REG_SZ*17+8`(%rsp),$num
|
||||
lea $REG_SZ($ctx),$ctx
|
||||
lea `16*$REG_SZ/4`($inp),$inp
|
||||
lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande_avx
|
||||
|
||||
@@ -1240,9 +1255,12 @@ $code.=<<___;
|
||||
lea `$REG_SZ*16`(%rsp),%rbx
|
||||
___
|
||||
for($i=0;$i<8;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -1313,7 +1331,7 @@ $code.=<<___;
|
||||
|
||||
#mov `$REG_SZ*17+8`(%rsp),$num
|
||||
#lea $REG_SZ($ctx),$ctx
|
||||
#lea `16*$REG_SZ/4`($inp),$inp
|
||||
#lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
#dec $num
|
||||
#jnz .Loop_grande_avx2
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
push(@INC,"${dir}","${dir}../../perlasm");
|
||||
require "x86_64-support.pl";
|
||||
|
||||
$ptr_size=&pointer_size($flavour);
|
||||
|
||||
$avx=0;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
@@ -93,6 +98,7 @@ $inp="%rsi"; # 2nd arg
|
||||
$num="%edx"; # 3rd arg
|
||||
@ptr=map("%r$_",(8..11));
|
||||
$Tbl="%rbp";
|
||||
$inp_elm_size=2*$ptr_size;
|
||||
|
||||
@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("%xmm$_",(8..15));
|
||||
($t1,$t2,$t3,$axb,$bxc,$Xi,$Xn,$sigma)=map("%xmm$_",(0..7));
|
||||
@@ -291,9 +297,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -392,7 +401,7 @@ $code.=<<___;
|
||||
|
||||
mov `$REG_SZ*17+8`(%rsp),$num
|
||||
lea $REG_SZ($ctx),$ctx
|
||||
lea `16*$REG_SZ/4`($inp),$inp
|
||||
lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande
|
||||
|
||||
@@ -470,9 +479,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<2;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -753,7 +765,7 @@ $code.=<<___;
|
||||
movq @MSG0[1],0xe0-0x80($ctx) # H1.H0
|
||||
|
||||
lea `$REG_SZ/2`($ctx),$ctx
|
||||
lea `16*2`($inp),$inp
|
||||
lea `$inp_elm_size*2`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande_shaext
|
||||
|
||||
@@ -990,9 +1002,12 @@ $code.=<<___;
|
||||
xor $num,$num
|
||||
___
|
||||
for($i=0;$i<4;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -1089,7 +1104,7 @@ $code.=<<___;
|
||||
|
||||
mov `$REG_SZ*17+8`(%rsp),$num
|
||||
lea $REG_SZ($ctx),$ctx
|
||||
lea `16*$REG_SZ/4`($inp),$inp
|
||||
lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
dec $num
|
||||
jnz .Loop_grande_avx
|
||||
|
||||
@@ -1180,9 +1195,12 @@ $code.=<<___;
|
||||
lea `$REG_SZ*16`(%rsp),%rbx
|
||||
___
|
||||
for($i=0;$i<8;$i++) {
|
||||
$ptr_reg=&pointer_register($flavour,@ptr[$i]);
|
||||
$code.=<<___;
|
||||
mov `16*$i+0`($inp),@ptr[$i] # input pointer
|
||||
mov `16*$i+8`($inp),%ecx # number of blocks
|
||||
# input pointer
|
||||
mov `$inp_elm_size*$i+0`($inp),$ptr_reg
|
||||
# number of blocks
|
||||
mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx
|
||||
cmp $num,%ecx
|
||||
cmovg %ecx,$num # find maximum
|
||||
test %ecx,%ecx
|
||||
@@ -1279,7 +1297,7 @@ $code.=<<___;
|
||||
|
||||
#mov `$REG_SZ*17+8`(%rsp),$num
|
||||
#lea $REG_SZ($ctx),$ctx
|
||||
#lea `16*$REG_SZ/4`($inp),$inp
|
||||
#lea `$inp_elm_size*$REG_SZ/4`($inp),$inp
|
||||
#dec $num
|
||||
#jnz .Loop_grande_avx2
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ SOURCE[../../libcrypto]=\
|
||||
x509_trs.c by_file.c by_dir.c by_store.c x509_vpm.c \
|
||||
x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \
|
||||
x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c \
|
||||
v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \
|
||||
v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_utf8.c v3_lib.c \
|
||||
v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c \
|
||||
v3_pku.c v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c \
|
||||
v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -23,3 +23,4 @@ extern const X509V3_EXT_METHOD v3_addr, v3_asid;
|
||||
extern const X509V3_EXT_METHOD v3_ct_scts[3];
|
||||
extern const X509V3_EXT_METHOD v3_tls_feature;
|
||||
extern const X509V3_EXT_METHOD v3_ext_admission;
|
||||
extern const X509V3_EXT_METHOD v3_utf8_list[1];
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -68,6 +68,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
|
||||
&v3_ct_scts[1],
|
||||
&v3_ct_scts[2],
|
||||
#endif
|
||||
&v3_utf8_list[0],
|
||||
&v3_tls_feature,
|
||||
&v3_ext_admission
|
||||
};
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <crypto/x509v3.h>
|
||||
#include "ext_dat.h"
|
||||
|
||||
/*
|
||||
* Subject Sign Tool (1.2.643.100.111) The name of the tool used to signs the subject (UTF8String)
|
||||
* This extention is required to obtain the status of a qualified certificate at Russian Federation.
|
||||
* RFC-style description is available here: https://tools.ietf.org/html/draft-deremin-rfc4491-bis-04#section-5
|
||||
* Russian Federal Law 63 "Digital Sign" is available here: http://www.consultant.ru/document/cons_doc_LAW_112701/
|
||||
*/
|
||||
|
||||
|
||||
const X509V3_EXT_METHOD v3_utf8_list[1] = {
|
||||
EXT_UTF8STRING(NID_subjectSignTool),
|
||||
};
|
||||
|
||||
char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method,
|
||||
ASN1_UTF8STRING *utf8)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (utf8 == NULL || utf8->length == 0) {
|
||||
X509V3err(X509V3_F_I2S_ASN1_UTF8STRING, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if ((tmp = OPENSSL_zalloc(utf8->length + 1)) == NULL) {
|
||||
X509V3err(X509V3_F_I2S_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(tmp, utf8->data, utf8->length);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx, const char *str)
|
||||
{
|
||||
ASN1_UTF8STRING *utf8;
|
||||
if (str == NULL) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, X509V3_R_INVALID_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if ((utf8 = ASN1_UTF8STRING_new()) == NULL) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)utf8, str, strlen(str))) {
|
||||
X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE);
|
||||
ASN1_UTF8STRING_free(utf8);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CHARSET_EBCDIC
|
||||
ebcdic2ascii(utf8->data, utf8->data, utf8->length);
|
||||
#endif /* CHARSET_EBCDIC */
|
||||
return utf8;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
||||
X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
} else if (pkey->pkeys[0].keymgmt != NULL) {
|
||||
} else if (pkey->keymgmt != NULL) {
|
||||
BIO *bmem = BIO_new(BIO_s_mem());
|
||||
const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
|
||||
OSSL_SERIALIZER_CTX *sctx =
|
||||
@@ -270,7 +270,7 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
|
||||
xpk->pkey = NULL;
|
||||
}
|
||||
X509_PUBKEY_free(xpk);
|
||||
} else if (a->pkeys[0].keymgmt != NULL) {
|
||||
} else if (a->keymgmt != NULL) {
|
||||
const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
|
||||
OSSL_SERIALIZER_CTX *ctx =
|
||||
OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
|
||||
|
||||
Reference in New Issue
Block a user