aboutsummaryrefslogtreecommitdiff
path: root/crypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/ec')
-rwxr-xr-xcrypto/ec/asm/ecp_nistp521-ppc64.pl436
-rwxr-xr-xcrypto/ec/asm/ecp_nistz256-armv4.pl18
-rw-r--r--crypto/ec/asm/ecp_nistz256-armv8.pl19
-rwxr-xr-xcrypto/ec/asm/ecp_nistz256-ppc64.pl13
-rwxr-xr-xcrypto/ec/asm/ecp_nistz256-sparcv9.pl12
-rwxr-xr-xcrypto/ec/asm/ecp_nistz256-x86.pl5
-rwxr-xr-xcrypto/ec/asm/ecp_nistz256-x86_64.pl14
-rwxr-xr-xcrypto/ec/asm/x25519-ppc64.pl11
-rwxr-xr-xcrypto/ec/asm/x25519-x86_64.pl12
-rw-r--r--crypto/ec/build.info129
-rw-r--r--crypto/ec/curve25519.c129
-rw-r--r--crypto/ec/curve448/arch_32/arch_intrinsics.h2
-rw-r--r--crypto/ec/curve448/arch_32/f_impl.h2
-rw-r--r--crypto/ec/curve448/arch_32/f_impl32.c (renamed from crypto/ec/curve448/arch_32/f_impl.c)16
-rw-r--r--crypto/ec/curve448/arch_64/arch_intrinsics.h27
-rw-r--r--crypto/ec/curve448/arch_64/f_impl.h58
-rw-r--r--crypto/ec/curve448/arch_64/f_impl64.c210
-rw-r--r--crypto/ec/curve448/curve448.c95
-rw-r--r--crypto/ec/curve448/curve448_local.h36
-rw-r--r--crypto/ec/curve448/curve448_tables.c8
-rw-r--r--crypto/ec/curve448/curve448utils.h10
-rw-r--r--crypto/ec/curve448/ed448.h92
-rw-r--r--crypto/ec/curve448/eddsa.c268
-rw-r--r--crypto/ec/curve448/f_generic.c6
-rw-r--r--crypto/ec/curve448/field.h13
-rw-r--r--crypto/ec/curve448/point_448.h71
-rw-r--r--crypto/ec/curve448/scalar.c51
-rw-r--r--crypto/ec/curve448/word.h15
-rw-r--r--crypto/ec/ec2_oct.c103
-rw-r--r--crypto/ec/ec2_smpl.c262
-rw-r--r--crypto/ec/ec_ameth.c775
-rw-r--r--crypto/ec/ec_asn1.c430
-rw-r--r--crypto/ec/ec_backend.c836
-rw-r--r--crypto/ec/ec_check.c62
-rw-r--r--crypto/ec/ec_curve.c300
-rw-r--r--crypto/ec/ec_cvt.c19
-rw-r--r--crypto/ec/ec_deprecated.c78
-rw-r--r--crypto/ec/ec_err.c317
-rw-r--r--crypto/ec/ec_key.c541
-rw-r--r--crypto/ec/ec_kmeth.c57
-rw-r--r--crypto/ec/ec_lib.c783
-rw-r--r--crypto/ec/ec_local.h562
-rw-r--r--crypto/ec/ec_mult.c144
-rw-r--r--crypto/ec/ec_oct.c58
-rw-r--r--crypto/ec/ec_pmeth.c115
-rw-r--r--crypto/ec/ec_print.c102
-rw-r--r--crypto/ec/ecdh_kdf.c92
-rw-r--r--crypto/ec/ecdh_ossl.c58
-rw-r--r--crypto/ec/ecdsa_ossl.c201
-rw-r--r--crypto/ec/ecdsa_sign.c16
-rw-r--r--crypto/ec/ecdsa_vrf.c12
-rw-r--r--crypto/ec/eck_prn.c59
-rw-r--r--crypto/ec/ecp_mont.c161
-rw-r--r--crypto/ec/ecp_nist.c120
-rw-r--r--crypto/ec/ecp_nistp224.c264
-rw-r--r--crypto/ec/ecp_nistp256.c290
-rw-r--r--crypto/ec/ecp_nistp521.c319
-rw-r--r--crypto/ec/ecp_nistputil.c33
-rw-r--r--crypto/ec/ecp_nistz256.c132
-rw-r--r--crypto/ec/ecp_nistz256_table.c2
-rw-r--r--crypto/ec/ecp_oct.c92
-rw-r--r--crypto/ec/ecp_ppc.c34
-rw-r--r--crypto/ec/ecp_s390x_nistp.c400
-rw-r--r--crypto/ec/ecp_smpl.c281
-rw-r--r--crypto/ec/ecx_backend.c263
-rw-r--r--crypto/ec/ecx_backend.h20
-rw-r--r--crypto/ec/ecx_key.c98
-rw-r--r--crypto/ec/ecx_meth.c951
-rw-r--r--crypto/ec/ecx_s390x.c217
69 files changed, 7925 insertions, 3512 deletions
diff --git a/crypto/ec/asm/ecp_nistp521-ppc64.pl b/crypto/ec/asm/ecp_nistp521-ppc64.pl
new file mode 100755
index 000000000000..cf3bc79085f8
--- /dev/null
+++ b/crypto/ec/asm/ecp_nistp521-ppc64.pl
@@ -0,0 +1,436 @@
+#! /usr/bin/env perl
+# Copyright 2021-2023 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
+#
+# ====================================================================
+# Written by Amitay Isaacs <amitay@ozlabs.org> and Martin Schwenke
+# <martin@meltin.net> for the OpenSSL project.
+# ====================================================================
+#
+# p521 lower-level primitives for PPC64 using vector instructions.
+#
+
+use strict;
+use warnings;
+
+my $flavour = shift;
+my $output = "";
+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
+if (!$output) {
+ $output = "-";
+}
+
+my ($xlate, $dir);
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+my $code = "";
+
+my ($sp, $outp, $savelr, $savesp) = ("r1", "r3", "r10", "r12");
+
+my $vzero = "v32";
+
+sub startproc($)
+{
+ my ($name) = @_;
+
+ $code.=<<___;
+ .globl ${name}
+ .align 5
+${name}:
+
+___
+}
+
+sub endproc($)
+{
+ my ($name) = @_;
+
+ $code.=<<___;
+ blr
+ .size ${name},.-${name}
+
+___
+}
+
+
+sub push_vrs($$)
+{
+ my ($min, $max) = @_;
+
+ my $count = $max - $min + 1;
+
+ $code.=<<___;
+ mr $savesp,$sp
+ stdu $sp,-16*`$count+1`($sp)
+
+___
+ for (my $i = $min; $i <= $max; $i++) {
+ my $mult = $max - $i + 1;
+ $code.=<<___;
+ stxv $i,-16*$mult($savesp)
+___
+
+ }
+
+ $code.=<<___;
+
+___
+}
+
+sub pop_vrs($$)
+{
+ my ($min, $max) = @_;
+
+ $code.=<<___;
+ ld $savesp,0($sp)
+___
+ for (my $i = $min; $i <= $max; $i++) {
+ my $mult = $max - $i + 1;
+ $code.=<<___;
+ lxv $i,-16*$mult($savesp)
+___
+ }
+
+ $code.=<<___;
+ mr $sp,$savesp
+
+___
+}
+
+sub load_vrs($$)
+{
+ my ($pointer, $reg_list) = @_;
+
+ for (my $i = 0; $i <= 8; $i++) {
+ my $offset = $i * 8;
+ $code.=<<___;
+ lxsd $reg_list->[$i],$offset($pointer)
+___
+ }
+
+ $code.=<<___;
+
+___
+}
+
+sub store_vrs($$)
+{
+ my ($pointer, $reg_list) = @_;
+
+ for (my $i = 0; $i <= 8; $i++) {
+ my $offset = $i * 16;
+ $code.=<<___;
+ stxv $reg_list->[$i],$offset($pointer)
+___
+ }
+
+ $code.=<<___;
+
+___
+}
+
+$code.=<<___;
+.machine "any"
+.text
+
+___
+
+{
+ # mul/square common
+ my ($t1, $t2, $t3, $t4) = ("v33", "v34", "v44", "v54");
+ my ($zero, $one) = ("r8", "r9");
+ my @out = map("v$_",(55..63));
+
+ {
+ #
+ # p521_felem_mul
+ #
+
+ my ($in1p, $in2p) = ("r4", "r5");
+ my @in1 = map("v$_",(45..53));
+ my @in2 = map("v$_",(35..43));
+
+ startproc("p521_felem_mul");
+
+ push_vrs(52, 63);
+
+ $code.=<<___;
+ vspltisw $vzero,0
+
+___
+
+ load_vrs($in1p, \@in1);
+ load_vrs($in2p, \@in2);
+
+ $code.=<<___;
+ vmsumudm $out[0],$in1[0],$in2[0],$vzero
+
+ xxpermdi $t1,$in1[0],$in1[1],0b00
+ xxpermdi $t2,$in2[1],$in2[0],0b00
+ vmsumudm $out[1],$t1,$t2,$vzero
+
+ xxpermdi $t2,$in2[2],$in2[1],0b00
+ vmsumudm $out[2],$t1,$t2,$vzero
+ vmsumudm $out[2],$in1[2],$in2[0],$out[2]
+
+ xxpermdi $t2,$in2[3],$in2[2],0b00
+ vmsumudm $out[3],$t1,$t2,$vzero
+ xxpermdi $t3,$in1[2],$in1[3],0b00
+ xxpermdi $t4,$in2[1],$in2[0],0b00
+ vmsumudm $out[3],$t3,$t4,$out[3]
+
+ xxpermdi $t2,$in2[4],$in2[3],0b00
+ vmsumudm $out[4],$t1,$t2,$vzero
+ xxpermdi $t4,$in2[2],$in2[1],0b00
+ vmsumudm $out[4],$t3,$t4,$out[4]
+ vmsumudm $out[4],$in1[4],$in2[0],$out[4]
+
+ xxpermdi $t2,$in2[5],$in2[4],0b00
+ vmsumudm $out[5],$t1,$t2,$vzero
+ xxpermdi $t4,$in2[3],$in2[2],0b00
+ vmsumudm $out[5],$t3,$t4,$out[5]
+
+ xxpermdi $t2,$in2[6],$in2[5],0b00
+ vmsumudm $out[6],$t1,$t2,$vzero
+ xxpermdi $t4,$in2[4],$in2[3],0b00
+ vmsumudm $out[6],$t3,$t4,$out[6]
+
+ xxpermdi $t2,$in2[7],$in2[6],0b00
+ vmsumudm $out[7],$t1,$t2,$vzero
+ xxpermdi $t4,$in2[5],$in2[4],0b00
+ vmsumudm $out[7],$t3,$t4,$out[7]
+
+ xxpermdi $t2,$in2[8],$in2[7],0b00
+ vmsumudm $out[8],$t1,$t2,$vzero
+ xxpermdi $t4,$in2[6],$in2[5],0b00
+ vmsumudm $out[8],$t3,$t4,$out[8]
+
+ xxpermdi $t1,$in1[4],$in1[5],0b00
+ xxpermdi $t2,$in2[1],$in2[0],0b00
+ vmsumudm $out[5],$t1,$t2,$out[5]
+
+ xxpermdi $t2,$in2[2],$in2[1],0b00
+ vmsumudm $out[6],$t1,$t2,$out[6]
+ vmsumudm $out[6],$in1[6],$in2[0],$out[6]
+
+ xxpermdi $t2,$in2[3],$in2[2],0b00
+ vmsumudm $out[7],$t1,$t2,$out[7]
+ xxpermdi $t3,$in1[6],$in1[7],0b00
+ xxpermdi $t4,$in2[1],$in2[0],0b00
+ vmsumudm $out[7],$t3,$t4,$out[7]
+
+ xxpermdi $t2,$in2[4],$in2[3],0b00
+ vmsumudm $out[8],$t1,$t2,$out[8]
+ xxpermdi $t4,$in2[2],$in2[1],0b00
+ vmsumudm $out[8],$t3,$t4,$out[8]
+ vmsumudm $out[8],$in1[8],$in2[0],$out[8]
+
+ li $zero,0
+ li $one,1
+ mtvsrdd $t1,$one,$zero
+___
+
+ for (my $i = 0; $i <= 8; $i++) {
+ $code.=<<___;
+ vsld $in2[$i],$in2[$i],$t1
+___
+ }
+
+ $code.=<<___;
+
+ vmsumudm $out[7],$in1[8],$in2[8],$out[7]
+
+ xxpermdi $t2,$in2[8],$in2[7],0b00
+ xxpermdi $t1,$in1[7],$in1[8],0b00
+ vmsumudm $out[6],$t1,$t2,$out[6]
+
+ xxpermdi $t1,$in1[6],$in1[7],0b00
+ vmsumudm $out[5],$t1,$t2,$out[5]
+ vmsumudm $out[5],$in1[8],$in2[6],$out[5]
+
+ xxpermdi $t1,$in1[5],$in1[6],0b00
+ vmsumudm $out[4],$t1,$t2,$out[4]
+ xxpermdi $t4,$in2[6],$in2[5],0b00
+ xxpermdi $t3,$in1[7],$in1[8],0b00
+ vmsumudm $out[4],$t3,$t4,$out[4]
+
+ xxpermdi $t1,$in1[4],$in1[5],0b00
+ vmsumudm $out[3],$t1,$t2,$out[3]
+ xxpermdi $t3,$in1[6],$in1[7],0b00
+ vmsumudm $out[3],$t3,$t4,$out[3]
+ vmsumudm $out[3],$in1[8],$in2[4],$out[3]
+
+ xxpermdi $t1,$in1[3],$in1[4],0b00
+ vmsumudm $out[2],$t1,$t2,$out[2]
+ xxpermdi $t3,$in1[5],$in1[6],0b00
+ vmsumudm $out[2],$t3,$t4,$out[2]
+
+ xxpermdi $t1,$in1[2],$in1[3],0b00
+ vmsumudm $out[1],$t1,$t2,$out[1]
+ xxpermdi $t3,$in1[4],$in1[5],0b00
+ vmsumudm $out[1],$t3,$t4,$out[1]
+
+ xxpermdi $t1,$in1[1],$in1[2],0b00
+ vmsumudm $out[0],$t1,$t2,$out[0]
+ xxpermdi $t3,$in1[3],$in1[4],0b00
+ vmsumudm $out[0],$t3,$t4,$out[0]
+
+ xxpermdi $t2,$in2[4],$in2[3],0b00
+ xxpermdi $t1,$in1[7],$in1[8],0b00
+ vmsumudm $out[2],$t1,$t2,$out[2]
+
+ xxpermdi $t1,$in1[6],$in1[7],0b00
+ vmsumudm $out[1],$t1,$t2,$out[1]
+ vmsumudm $out[1],$in1[8],$in2[2],$out[1]
+
+ xxpermdi $t1,$in1[5],$in1[6],0b00
+ vmsumudm $out[0],$t1,$t2,$out[0]
+ xxpermdi $t4,$in2[2],$in2[1],0b00
+ xxpermdi $t3,$in1[7],$in1[8],0b00
+ vmsumudm $out[0],$t3,$t4,$out[0]
+
+___
+
+ store_vrs($outp, \@out);
+
+ pop_vrs(52, 63);
+
+ endproc("p521_felem_mul");
+ }
+
+ {
+ #
+ # p51_felem_square
+ #
+
+ my ($inp) = ("r4");
+ my @in = map("v$_",(45..53));
+ my @inx2 = map("v$_",(35..43));
+
+ startproc("p521_felem_square");
+
+ push_vrs(52, 63);
+
+ $code.=<<___;
+ vspltisw $vzero,0
+
+___
+
+ load_vrs($inp, \@in);
+
+ $code.=<<___;
+ li $zero,0
+ li $one,1
+ mtvsrdd $t1,$one,$zero
+___
+
+ for (my $i = 0; $i <= 8; $i++) {
+ $code.=<<___;
+ vsld $inx2[$i],$in[$i],$t1
+___
+ }
+
+ $code.=<<___;
+ vmsumudm $out[0],$in[0],$in[0],$vzero
+
+ vmsumudm $out[1],$in[0],$inx2[1],$vzero
+
+ xxpermdi $t1,$in[0],$in[1],0b00
+ xxpermdi $t2,$inx2[2],$in[1],0b00
+ vmsumudm $out[2],$t1,$t2,$vzero
+
+ xxpermdi $t2,$inx2[3],$inx2[2],0b00
+ vmsumudm $out[3],$t1,$t2,$vzero
+
+ xxpermdi $t2,$inx2[4],$inx2[3],0b00
+ vmsumudm $out[4],$t1,$t2,$vzero
+ vmsumudm $out[4],$in[2],$in[2],$out[4]
+
+ xxpermdi $t2,$inx2[5],$inx2[4],0b00
+ vmsumudm $out[5],$t1,$t2,$vzero
+ vmsumudm $out[5],$in[2],$inx2[3],$out[5]
+
+ xxpermdi $t2,$inx2[6],$inx2[5],0b00
+ vmsumudm $out[6],$t1,$t2,$vzero
+ xxpermdi $t3,$in[2],$in[3],0b00
+ xxpermdi $t4,$inx2[4],$in[3],0b00
+ vmsumudm $out[6],$t3,$t4,$out[6]
+
+ xxpermdi $t2,$inx2[7],$inx2[6],0b00
+ vmsumudm $out[7],$t1,$t2,$vzero
+ xxpermdi $t4,$inx2[5],$inx2[4],0b00
+ vmsumudm $out[7],$t3,$t4,$out[7]
+
+ xxpermdi $t2,$inx2[8],$inx2[7],0b00
+ vmsumudm $out[8],$t1,$t2,$vzero
+ xxpermdi $t4,$inx2[6],$inx2[5],0b00
+ vmsumudm $out[8],$t3,$t4,$out[8]
+ vmsumudm $out[8],$in[4],$in[4],$out[8]
+
+ vmsumudm $out[1],$in[5],$inx2[5],$out[1]
+
+ vmsumudm $out[3],$in[6],$inx2[6],$out[3]
+
+ vmsumudm $out[5],$in[7],$inx2[7],$out[5]
+
+ vmsumudm $out[7],$in[8],$inx2[8],$out[7]
+
+ mtvsrdd $t1,$one,$zero
+___
+
+ for (my $i = 5; $i <= 8; $i++) {
+ $code.=<<___;
+ vsld $inx2[$i],$inx2[$i],$t1
+___
+ }
+
+ $code.=<<___;
+
+ vmsumudm $out[6],$in[7],$inx2[8],$out[6]
+
+ vmsumudm $out[5],$in[6],$inx2[8],$out[5]
+
+ xxpermdi $t2,$inx2[8],$inx2[7],0b00
+ xxpermdi $t1,$in[5],$in[6],0b00
+ vmsumudm $out[4],$t1,$t2,$out[4]
+
+ xxpermdi $t1,$in[4],$in[5],0b00
+ vmsumudm $out[3],$t1,$t2,$out[3]
+
+ xxpermdi $t1,$in[3],$in[4],0b00
+ vmsumudm $out[2],$t1,$t2,$out[2]
+ vmsumudm $out[2],$in[5],$inx2[6],$out[2]
+
+ xxpermdi $t1,$in[2],$in[3],0b00
+ vmsumudm $out[1],$t1,$t2,$out[1]
+ vmsumudm $out[1],$in[4],$inx2[6],$out[1]
+
+ xxpermdi $t1,$in[1],$in[2],0b00
+ vmsumudm $out[0],$t1,$t2,$out[0]
+ xxpermdi $t2,$inx2[6],$inx2[5],0b00
+ xxpermdi $t1,$in[3],$in[4],0b00
+ vmsumudm $out[0],$t1,$t2,$out[0]
+
+___
+
+ store_vrs($outp, \@out);
+
+ pop_vrs(52, 63);
+
+ endproc("p521_felem_square");
+ }
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl
index fa833ce6aaf3..0adad26cb11f 100755
--- a/crypto/ec/asm/ecp_nistz256-armv4.pl
+++ b/crypto/ec/asm/ecp_nistz256-armv4.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -33,9 +33,10 @@
# on benchmark. Lower coefficients are for ECDSA sign, server-side
# operation. Keep in mind that +200% means 3x improvement.
-$flavour = shift;
-if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
@@ -43,15 +44,15 @@ if ($flavour && $flavour ne "void") {
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
- open STDOUT,"| \"$^X\" $xlate $flavour $output";
+ open STDOUT,"| \"$^X\" $xlate $flavour \"$output\""
+ or die "can't call $xlate: $!";
} else {
- open STDOUT,">$output";
+ $output and open STDOUT,">$output";
}
$code.=<<___;
#include "arm_arch.h"
-.text
#if defined(__thumb2__)
.syntax unified
.thumb
@@ -80,6 +81,7 @@ close TABLE;
die "insane number of elements" if ($#arr != 64*16*37-1);
$code.=<<___;
+.rodata
.globl ecp_nistz256_precomputed
.type ecp_nistz256_precomputed,%object
.align 12
@@ -104,6 +106,8 @@ for(1..37) {
}
$code.=<<___;
.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
+
+.text
.align 5
.LRR: @ 2^512 mod P precomputed for NIST P256 polynomial
.long 0x00000003, 0x00000000, 0xffffffff, 0xfffffffb
diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl
index e93e18f29f19..81ee3947d7e4 100644
--- a/crypto/ec/asm/ecp_nistz256-armv8.pl
+++ b/crypto/ec/asm/ecp_nistz256-armv8.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -31,15 +31,18 @@
# on benchmark. Lower coefficients are for ECDSA sign, server-side
# operation. Keep in mind that +400% means 5x improvement.
-$flavour = shift;
-while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
-open OUT,"| \"$^X\" $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour \"$output\""
+ or die "can't call $xlate: $!";
*STDOUT=*OUT;
{
@@ -1479,7 +1482,7 @@ $code.=<<___;
////////////////////////////////////////////////////////////////////////
// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
-// int rep);
+// uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.type ecp_nistz256_ord_sqr_mont,%function
.align 4
@@ -1645,7 +1648,7 @@ ecp_nistz256_scatter_w5:
ldp x4,x5,[$inp] // X
ldp x6,x7,[$inp,#16]
- str w4,[$out,#64*0-4]
+ stur w4,[$out,#64*0-4]
lsr x4,x4,#32
str w5,[$out,#64*1-4]
lsr x5,x5,#32
@@ -1661,7 +1664,7 @@ ecp_nistz256_scatter_w5:
ldp x4,x5,[$inp,#32] // Y
ldp x6,x7,[$inp,#48]
- str w4,[$out,#64*0-4]
+ stur w4,[$out,#64*0-4]
lsr x4,x4,#32
str w5,[$out,#64*1-4]
lsr x5,x5,#32
@@ -1677,7 +1680,7 @@ ecp_nistz256_scatter_w5:
ldp x4,x5,[$inp,#64] // Z
ldp x6,x7,[$inp,#80]
- str w4,[$out,#64*0-4]
+ stur w4,[$out,#64*0-4]
lsr x4,x4,#32
str w5,[$out,#64*1-4]
lsr x5,x5,#32
diff --git a/crypto/ec/asm/ecp_nistz256-ppc64.pl b/crypto/ec/asm/ecp_nistz256-ppc64.pl
index 2bf54e2aa544..7f600cece9d7 100755
--- a/crypto/ec/asm/ecp_nistz256-ppc64.pl
+++ b/crypto/ec/asm/ecp_nistz256-ppc64.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -25,15 +25,18 @@
# POWER7 +260-530%
# POWER8 +220-340%
-$flavour = shift;
-while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
die "can't locate ppc-xlate.pl";
-open OUT,"| \"$^X\" $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour \"$output\""
+ or die "can't call $xlate: $!";
*STDOUT=*OUT;
my $sp="r1";
@@ -1919,7 +1922,7 @@ $code.=<<___;
################################################################################
# void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
-# int rep);
+# uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.align 5
ecp_nistz256_ord_sqr_mont:
diff --git a/crypto/ec/asm/ecp_nistz256-sparcv9.pl b/crypto/ec/asm/ecp_nistz256-sparcv9.pl
index 042e122718b7..986e002cc94d 100755
--- a/crypto/ec/asm/ecp_nistz256-sparcv9.pl
+++ b/crypto/ec/asm/ecp_nistz256-sparcv9.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
-# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -31,11 +31,13 @@
# on benchmark. Lower coefficients are for ECDSA sign, server-side
# operation. Keep in mind that +200% means 3x improvement.
-$output = pop;
-open STDOUT,">$output";
+$output = pop and open STDOUT,">$output";
$code.=<<___;
-#include "sparc_arch.h"
+#ifndef __ASSEMBLER__
+# define __ASSEMBLER__ 1
+#endif
+#include "crypto/sparc_arch.h"
#define LOCALS (STACK_BIAS+STACK_FRAME)
#ifdef __arch64__
diff --git a/crypto/ec/asm/ecp_nistz256-x86.pl b/crypto/ec/asm/ecp_nistz256-x86.pl
index e926d69b020b..e78f0cd7266d 100755
--- a/crypto/ec/asm/ecp_nistz256-x86.pl
+++ b/crypto/ec/asm/ecp_nistz256-x86.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -42,8 +42,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
push(@INC,"${dir}","${dir}../../perlasm");
require "x86asm.pl";
-$output=pop;
-open STDOUT,">$output";
+$output=pop and open STDOUT,">$output";
&asm_init($ARGV[0],$ARGV[$#ARGV] eq "386");
diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl
index b50ee70191b2..430b14c86d8d 100755
--- a/crypto/ec/asm/ecp_nistz256-x86_64.pl
+++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl
@@ -3,7 +3,7 @@
# Copyright (c) 2014, Intel Corporation. All Rights Reserved.
# Copyright (c) 2015 CloudFlare, Inc.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -40,9 +40,10 @@
# higher - for ECDSA sign, relatively fastest server-side operation.
# Keep in mind that +100% means 2x improvement.
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
@@ -51,7 +52,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
+ or die "can't call $xlate: $!";
*STDOUT=*OUT;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
@@ -826,7 +828,7 @@ $code.=<<___;
# void ecp_nistz256_ord_sqr_mont(
# uint64_t res[4],
# uint64_t a[4],
-# int rep);
+# uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.type ecp_nistz256_ord_sqr_mont,\@function,3
diff --git a/crypto/ec/asm/x25519-ppc64.pl b/crypto/ec/asm/x25519-ppc64.pl
index f4b523bf8a08..c1d9650c6bfa 100755
--- a/crypto/ec/asm/x25519-ppc64.pl
+++ b/crypto/ec/asm/x25519-ppc64.pl
@@ -1,7 +1,7 @@
#! /usr/bin/env perl
# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -27,15 +27,18 @@
# this module delivers more than 2x improvement, and when it does,
# from 12% to 30% improvement was measured...
-$flavour = shift;
-while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
die "can't locate ppc-xlate.pl";
-open OUT,"| \"$^X\" $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour \"$output\""
+ or die "can't call $xlate: $!";
*STDOUT=*OUT;
my $sp = "r1";
diff --git a/crypto/ec/asm/x25519-x86_64.pl b/crypto/ec/asm/x25519-x86_64.pl
index 62599dacaccd..d2285269a308 100755
--- a/crypto/ec/asm/x25519-x86_64.pl
+++ b/crypto/ec/asm/x25519-x86_64.pl
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
@@ -61,9 +61,10 @@
# C implementation, so that comparison is always against
# 2^51 radix;
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
@@ -72,7 +73,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
+ or die "can't call $xlate: $!";
*STDOUT=*OUT;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
diff --git a/crypto/ec/build.info b/crypto/ec/build.info
index a1e673e347d0..6dd98e9f4f17 100644
--- a/crypto/ec/build.info
+++ b/crypto/ec/build.info
@@ -1,42 +1,105 @@
-LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
- ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
- ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \
- ec2_smpl.c ec_ameth.c ec_pmeth.c eck_prn.c \
- ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
- ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
- ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
- curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
+$ECASM=
+IF[{- !$disabled{asm} -}]
+ $ECASM_x86=ecp_nistz256.c ecp_nistz256-x86.S
+ $ECDEF_x86=ECP_NISTZ256_ASM
+
+ $ECASM_x86_64=ecp_nistz256.c ecp_nistz256-x86_64.s x25519-x86_64.s
+ $ECDEF_x86_64=ECP_NISTZ256_ASM X25519_ASM
+
+ $ECASM_ia64=
+
+ $ECASM_sparcv9=ecp_nistz256.c ecp_nistz256-sparcv9.S
+ $ECDEF_sparcv9=ECP_NISTZ256_ASM
+
+ $ECASM_sparcv8=
+
+ $ECASM_alpha=
+
+ $ECASM_mips32=
+ $ECASM_mips64=
+
+ $ECASM_s390x=ecp_s390x_nistp.c ecx_s390x.c
+ $ECDEF_s390x=S390X_EC_ASM
+
+ $ECASM_armv4=ecp_nistz256.c ecp_nistz256-armv4.S
+ $ECDEF_armv4=ECP_NISTZ256_ASM
+ $ECASM_aarch64=ecp_nistz256.c ecp_nistz256-armv8.S
+ $ECDEF_aarch64=ECP_NISTZ256_ASM
+
+ $ECASM_parisc11=
+ $ECASM_parisc20_64=
+
+ $ECASM_ppc32=
+ $ECASM_ppc64=ecp_nistz256.c ecp_ppc.c ecp_nistz256-ppc64.s x25519-ppc64.s
+ $ECDEF_ppc64=ECP_NISTZ256_ASM X25519_ASM
+ IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}]
+ $ECASM_ppc64=$ECASM_ppc64 ecp_nistp521-ppc64.s
+ $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP521_ASM
+ INCLUDE[ecp_nistp521.o]=..
+ ENDIF
+
+ $ECASM_c64xplus=
+
+ # Now that we have defined all the arch specific variables, use the
+ # appropriate one, and define the appropriate macros
+ IF[$ECASM_{- $target{asm_arch} -}]
+ $ECASM=$ECASM_{- $target{asm_arch} -}
+ $ECDEF=$ECDEF_{- $target{asm_arch} -}
+ ENDIF
+ENDIF
+
+$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_key.c ec_kmeth.c ecx_key.c ec_asn1.c \
+ ec2_smpl.c \
+ ecp_oct.c ec2_oct.c ec_oct.c ecdh_ossl.c \
+ ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
+ curve448/f_generic.c curve448/scalar.c \
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
- {- $target{ec_asm_src} -}
+ $ECASM ec_backend.c ecx_backend.c ecdh_kdf.c curve448/arch_64/f_impl64.c \
+ curve448/arch_32/f_impl32.c
+
+IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}]
+ $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c
+ENDIF
+
+SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c \
+ ec_err.c eck_prn.c \
+ ec_deprecated.c ec_print.c
+SOURCE[../../providers/libfips.a]=$COMMON
-GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl \
- $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR)
+# Implementations are now spread across several libraries, so the defines
+# need to be applied to all affected libraries and modules.
+DEFINE[../../libcrypto]=$ECDEF
+DEFINE[../../providers/libfips.a]=$ECDEF
+DEFINE[../../providers/libdefault.a]=$ECDEF
+# We only need to include the ECDEF stuff in the legacy provider when
+# it's a separate module and it's dynamically linked with libcrypto.
+# Otherwise, it already gets everything that the static libcrypto.a
+# has, and doesn't need it added again.
+IF[{- !$disabled{module} && !$disabled{shared} -}]
+ DEFINE[../../providers/liblegacy.a]=$ECDEF
+ENDIF
-GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME)
+GENERATE[ecp_nistz256-x86.S]=asm/ecp_nistz256-x86.pl
-GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME)
+GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl
-GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME)
+GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl
+
+GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl
INCLUDE[ecp_nistz256-sparcv9.o]=..
-GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME)
+INCLUDE[ecp_s390x_nistp.o]=..
+INCLUDE[ecx_s390x.o]=..
+INCLUDE[ecx_meth.o]=..
+
+GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl
INCLUDE[ecp_nistz256-armv4.o]=..
-GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME)
+GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl
INCLUDE[ecp_nistz256-armv8.o]=..
-GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl $(PERLASM_SCHEME)
-
-GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl $(PERLASM_SCHEME)
-GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl $(PERLASM_SCHEME)
-
-BEGINRAW[Makefile]
-{- $builddir -}/ecp_nistz256-%.S: {- $sourcedir -}/asm/ecp_nistz256-%.pl
- CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-ENDRAW[Makefile]
-
-INCLUDE[curve448/arch_32/f_impl.o]=curve448/arch_32 curve448
-INCLUDE[curve448/f_generic.o]=curve448/arch_32 curve448
-INCLUDE[curve448/scalar.o]=curve448/arch_32 curve448
-INCLUDE[curve448/curve448_tables.o]=curve448/arch_32 curve448
-INCLUDE[curve448/eddsa.o]=curve448/arch_32 curve448
-INCLUDE[curve448/curve448.o]=curve448/arch_32 curve448
+GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl
+
+GENERATE[ecp_nistp521-ppc64.s]=asm/ecp_nistp521-ppc64.pl
+
+GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl
+GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl
diff --git a/crypto/ec/curve25519.c b/crypto/ec/curve25519.c
index 952da0e65385..50a8e6b169d2 100644
--- a/crypto/ec/curve25519.c
+++ b/crypto/ec/curve25519.c
@@ -1,16 +1,26 @@
/*
- * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
+#include "crypto/ecx.h"
#include "ec_local.h"
+#include <openssl/evp.h>
#include <openssl/sha.h>
+#include "internal/numbers.h"
+
#if defined(X25519_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64))
@@ -252,7 +262,7 @@ static void x25519_scalar_mulx(uint8_t out[32], const uint8_t scalar[32],
#endif
#if defined(X25519_ASM) \
- || ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \
+ || ( defined(INT128_MAX) \
&& !defined(__sparc__) \
&& (!defined(__SIZEOF_LONG__) || (__SIZEOF_LONG__ == 8)) \
&& !(defined(__ANDROID__) && !defined(__clang__)) )
@@ -385,7 +395,7 @@ void x25519_fe51_mul121666(fe51 h, fe51 f);
# define fe51_mul121666 x25519_fe51_mul121666
# else
-typedef __uint128_t u128;
+typedef uint128_t u128;
static void fe51_mul(fe51 h, const fe51 f, const fe51 g)
{
@@ -5429,57 +5439,75 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
s[31] = (uint8_t) (s11 >> 17);
}
-int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t public_key[32], const uint8_t private_key[32])
+int
+ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
+ const uint8_t public_key[32], const uint8_t private_key[32],
+ OSSL_LIB_CTX *libctx, const char *propq)
{
uint8_t az[SHA512_DIGEST_LENGTH];
uint8_t nonce[SHA512_DIGEST_LENGTH];
ge_p3 R;
uint8_t hram[SHA512_DIGEST_LENGTH];
- SHA512_CTX hash_ctx;
+ EVP_MD *sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
+ EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
+ unsigned int sz;
+ int res = 0;
- SHA512_Init(&hash_ctx);
- SHA512_Update(&hash_ctx, private_key, 32);
- SHA512_Final(az, &hash_ctx);
+ if (sha512 == NULL || hash_ctx == NULL)
+ goto err;
+
+ if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL)
+ || !EVP_DigestUpdate(hash_ctx, private_key, 32)
+ || !EVP_DigestFinal_ex(hash_ctx, az, &sz))
+ goto err;
az[0] &= 248;
az[31] &= 63;
az[31] |= 64;
- SHA512_Init(&hash_ctx);
- SHA512_Update(&hash_ctx, az + 32, 32);
- SHA512_Update(&hash_ctx, message, message_len);
- SHA512_Final(nonce, &hash_ctx);
+ if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL)
+ || !EVP_DigestUpdate(hash_ctx, az + 32, 32)
+ || !EVP_DigestUpdate(hash_ctx, message, message_len)
+ || !EVP_DigestFinal_ex(hash_ctx, nonce, &sz))
+ goto err;
x25519_sc_reduce(nonce);
ge_scalarmult_base(&R, nonce);
ge_p3_tobytes(out_sig, &R);
- SHA512_Init(&hash_ctx);
- SHA512_Update(&hash_ctx, out_sig, 32);
- SHA512_Update(&hash_ctx, public_key, 32);
- SHA512_Update(&hash_ctx, message, message_len);
- SHA512_Final(hram, &hash_ctx);
+ if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL)
+ || !EVP_DigestUpdate(hash_ctx, out_sig, 32)
+ || !EVP_DigestUpdate(hash_ctx, public_key, 32)
+ || !EVP_DigestUpdate(hash_ctx, message, message_len)
+ || !EVP_DigestFinal_ex(hash_ctx, hram, &sz))
+ goto err;
x25519_sc_reduce(hram);
sc_muladd(out_sig + 32, hram, az, nonce);
- OPENSSL_cleanse(&hash_ctx, sizeof(hash_ctx));
+ res = 1;
+err:
OPENSSL_cleanse(nonce, sizeof(nonce));
OPENSSL_cleanse(az, sizeof(az));
-
- return 1;
+ EVP_MD_free(sha512);
+ EVP_MD_CTX_free(hash_ctx);
+ return res;
}
static const char allzeroes[15];
-int ED25519_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[64], const uint8_t public_key[32])
+int
+ossl_ed25519_verify(const uint8_t *message, size_t message_len,
+ const uint8_t signature[64], const uint8_t public_key[32],
+ OSSL_LIB_CTX *libctx, const char *propq)
{
int i;
ge_p3 A;
const uint8_t *r, *s;
- SHA512_CTX hash_ctx;
+ EVP_MD *sha512;
+ EVP_MD_CTX *hash_ctx = NULL;
+ unsigned int sz;
+ int res = 0;
ge_p2 R;
uint8_t rcheck[32];
uint8_t h[SHA512_DIGEST_LENGTH];
@@ -5526,11 +5554,19 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
fe_neg(A.X, A.X);
fe_neg(A.T, A.T);
- SHA512_Init(&hash_ctx);
- SHA512_Update(&hash_ctx, r, 32);
- SHA512_Update(&hash_ctx, public_key, 32);
- SHA512_Update(&hash_ctx, message, message_len);
- SHA512_Final(h, &hash_ctx);
+ sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
+ if (sha512 == NULL)
+ return 0;
+ hash_ctx = EVP_MD_CTX_new();
+ if (hash_ctx == NULL)
+ goto err;
+
+ if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL)
+ || !EVP_DigestUpdate(hash_ctx, r, 32)
+ || !EVP_DigestUpdate(hash_ctx, public_key, 32)
+ || !EVP_DigestUpdate(hash_ctx, message, message_len)
+ || !EVP_DigestFinal_ex(hash_ctx, h, &sz))
+ goto err;
x25519_sc_reduce(h);
@@ -5538,16 +5574,32 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
ge_tobytes(rcheck, &R);
- return CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0;
+ res = CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0;
+err:
+ EVP_MD_free(sha512);
+ EVP_MD_CTX_free(hash_ctx);
+ return res;
}
-void ED25519_public_from_private(uint8_t out_public_key[32],
- const uint8_t private_key[32])
+int
+ossl_ed25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[32],
+ const uint8_t private_key[32],
+ const char *propq)
{
uint8_t az[SHA512_DIGEST_LENGTH];
ge_p3 A;
+ int r;
+ EVP_MD *sha512 = NULL;
- SHA512(private_key, 32, az);
+ sha512 = EVP_MD_fetch(ctx, SN_sha512, propq);
+ if (sha512 == NULL)
+ return 0;
+ r = EVP_Digest(private_key, 32, az, NULL, sha512, NULL);
+ EVP_MD_free(sha512);
+ if (!r) {
+ OPENSSL_cleanse(az, sizeof(az));
+ return 0;
+ }
az[0] &= 248;
az[31] &= 63;
@@ -5557,10 +5609,12 @@ void ED25519_public_from_private(uint8_t out_public_key[32],
ge_p3_tobytes(out_public_key, &A);
OPENSSL_cleanse(az, sizeof(az));
+ return 1;
}
-int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
- const uint8_t peer_public_value[32])
+int
+ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
+ const uint8_t peer_public_value[32])
{
static const uint8_t kZeros[32] = {0};
x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
@@ -5568,7 +5622,8 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
}
-void X25519_public_from_private(uint8_t out_public_value[32],
+void
+ossl_x25519_public_from_private(uint8_t out_public_value[32],
const uint8_t private_key[32])
{
uint8_t e[32];
diff --git a/crypto/ec/curve448/arch_32/arch_intrinsics.h b/crypto/ec/curve448/arch_32/arch_intrinsics.h
index 5f6389863d15..7a54903ac95a 100644
--- a/crypto/ec/curve448/arch_32/arch_intrinsics.h
+++ b/crypto/ec/curve448/arch_32/arch_intrinsics.h
@@ -2,7 +2,7 @@
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
diff --git a/crypto/ec/curve448/arch_32/f_impl.h b/crypto/ec/curve448/arch_32/f_impl.h
index e1ddddaee08d..5cd25c04e123 100644
--- a/crypto/ec/curve448/arch_32/f_impl.h
+++ b/crypto/ec/curve448/arch_32/f_impl.h
@@ -2,7 +2,7 @@
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2014-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
diff --git a/crypto/ec/curve448/arch_32/f_impl.c b/crypto/ec/curve448/arch_32/f_impl32.c
index 8a89d276edb6..8714a5142216 100644
--- a/crypto/ec/curve448/arch_32/f_impl.c
+++ b/crypto/ec/curve448/arch_32/f_impl32.c
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2014 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -10,7 +10,16 @@
* Originally written by Mike Hamburg
*/
-#include "field.h"
+#include "e_os.h"
+#include <openssl/macros.h>
+#include "internal/numbers.h"
+
+#ifdef UINT128_MAX
+/* We have support for 128 bit ints, so do nothing here */
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "../field.h"
void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs)
{
@@ -93,3 +102,4 @@ void gf_sqr(gf_s * RESTRICT cs, const gf as)
{
gf_mul(cs, as, as); /* Performs better with a dedicated square */
}
+#endif
diff --git a/crypto/ec/curve448/arch_64/arch_intrinsics.h b/crypto/ec/curve448/arch_64/arch_intrinsics.h
new file mode 100644
index 000000000000..e12b8cf22624
--- /dev/null
+++ b/crypto/ec/curve448/arch_64/arch_intrinsics.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016 Cryptography Research, Inc.
+ *
+ * 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
+ *
+ * Originally written by Mike Hamburg
+ */
+
+#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H
+# define OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H
+
+# include "internal/constant_time.h"
+
+# define ARCH_WORD_BITS 64
+
+# define word_is_zero(a) constant_time_is_zero_64(a)
+
+static ossl_inline uint128_t widemul(uint64_t a, uint64_t b)
+{
+ return ((uint128_t) a) * b;
+}
+
+#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H */
diff --git a/crypto/ec/curve448/arch_64/f_impl.h b/crypto/ec/curve448/arch_64/f_impl.h
new file mode 100644
index 000000000000..faaeb8d9944b
--- /dev/null
+++ b/crypto/ec/curve448/arch_64/f_impl.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2016 Cryptography Research, Inc.
+ *
+ * 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
+ *
+ * Originally written by Mike Hamburg
+ */
+
+#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H
+# define OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H
+
+# define GF_HEADROOM 9999 /* Everything is reduced anyway */
+# define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}}
+
+# define LIMB_PLACE_VALUE(i) 56
+
+void gf_add_RAW(gf out, const gf a, const gf b)
+{
+ unsigned int i;
+
+ for (i = 0; i < NLIMBS; i++)
+ out->limb[i] = a->limb[i] + b->limb[i];
+
+ gf_weak_reduce(out);
+}
+
+void gf_sub_RAW(gf out, const gf a, const gf b)
+{
+ uint64_t co1 = ((1ULL << 56) - 1) * 2, co2 = co1 - 2;
+ unsigned int i;
+
+ for (i = 0; i < NLIMBS; i++)
+ out->limb[i] = a->limb[i] - b->limb[i] + ((i == NLIMBS / 2) ? co2 : co1);
+
+ gf_weak_reduce(out);
+}
+
+void gf_bias(gf a, int amt)
+{
+}
+
+void gf_weak_reduce(gf a)
+{
+ uint64_t mask = (1ULL << 56) - 1;
+ uint64_t tmp = a->limb[NLIMBS - 1] >> 56;
+ unsigned int i;
+
+ a->limb[NLIMBS / 2] += tmp;
+ for (i = NLIMBS - 1; i > 0; i--)
+ a->limb[i] = (a->limb[i] & mask) + (a->limb[i - 1] >> 56);
+ a->limb[0] = (a->limb[0] & mask) + tmp;
+}
+
+#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H */
diff --git a/crypto/ec/curve448/arch_64/f_impl64.c b/crypto/ec/curve448/arch_64/f_impl64.c
new file mode 100644
index 000000000000..dfe75b8fc5ca
--- /dev/null
+++ b/crypto/ec/curve448/arch_64/f_impl64.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014 Cryptography Research, Inc.
+ *
+ * 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
+ *
+ * Originally written by Mike Hamburg
+ */
+
+#include "e_os.h"
+#include <openssl/macros.h>
+#include "internal/numbers.h"
+
+#ifndef UINT128_MAX
+/* No support for 128 bit ints, so do nothing here */
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "../field.h"
+
+void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs)
+{
+ const uint64_t *a = as->limb, *b = bs->limb;
+ uint64_t *c = cs->limb;
+ uint128_t accum0 = 0, accum1 = 0, accum2;
+ uint64_t mask = (1ULL << 56) - 1;
+ uint64_t aa[4], bb[4], bbb[4];
+ unsigned int i, j;
+
+ for (i = 0; i < 4; i++) {
+ aa[i] = a[i] + a[i + 4];
+ bb[i] = b[i] + b[i + 4];
+ bbb[i] = bb[i] + b[i + 4];
+ }
+
+ for (i = 0; i < 4; i++) {
+ accum2 = 0;
+
+ for (j = 0; j <= i; j++) {
+ accum2 += widemul(a[j], b[i - j]);
+ accum1 += widemul(aa[j], bb[i - j]);
+ accum0 += widemul(a[j + 4], b[i - j + 4]);
+ }
+ for (; j < 4; j++) {
+ accum2 += widemul(a[j], b[i + 8 - j]);
+ accum1 += widemul(aa[j], bbb[i + 4 - j]);
+ accum0 += widemul(a[j + 4], bb[i + 4 - j]);
+ }
+
+ accum1 -= accum2;
+ accum0 += accum2;
+
+ c[i] = ((uint64_t)(accum0)) & mask;
+ c[i + 4] = ((uint64_t)(accum1)) & mask;
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+ }
+
+ accum0 += accum1;
+ accum0 += c[4];
+ accum1 += c[0];
+ c[4] = ((uint64_t)(accum0)) & mask;
+ c[0] = ((uint64_t)(accum1)) & mask;
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+
+ c[5] += ((uint64_t)(accum0));
+ c[1] += ((uint64_t)(accum1));
+}
+
+void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b)
+{
+ const uint64_t *a = as->limb;
+ uint64_t *c = cs->limb;
+ uint128_t accum0 = 0, accum4 = 0;
+ uint64_t mask = (1ULL << 56) - 1;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ accum0 += widemul(b, a[i]);
+ accum4 += widemul(b, a[i + 4]);
+ c[i] = accum0 & mask;
+ accum0 >>= 56;
+ c[i + 4] = accum4 & mask;
+ accum4 >>= 56;
+ }
+
+ accum0 += accum4 + c[4];
+ c[4] = accum0 & mask;
+ c[5] += accum0 >> 56;
+
+ accum4 += c[0];
+ c[0] = accum4 & mask;
+ c[1] += accum4 >> 56;
+}
+
+void gf_sqr(gf_s * RESTRICT cs, const gf as)
+{
+ const uint64_t *a = as->limb;
+ uint64_t *c = cs->limb;
+ uint128_t accum0 = 0, accum1 = 0, accum2;
+ uint64_t mask = (1ULL << 56) - 1;
+ uint64_t aa[4];
+ unsigned int i;
+
+ /* For some reason clang doesn't vectorize this without prompting? */
+ for (i = 0; i < 4; i++)
+ aa[i] = a[i] + a[i + 4];
+
+ accum2 = widemul(a[0], a[3]);
+ accum0 = widemul(aa[0], aa[3]);
+ accum1 = widemul(a[4], a[7]);
+
+ accum2 += widemul(a[1], a[2]);
+ accum0 += widemul(aa[1], aa[2]);
+ accum1 += widemul(a[5], a[6]);
+
+ accum0 -= accum2;
+ accum1 += accum2;
+
+ c[3] = ((uint64_t)(accum1)) << 1 & mask;
+ c[7] = ((uint64_t)(accum0)) << 1 & mask;
+
+ accum0 >>= 55;
+ accum1 >>= 55;
+
+ accum0 += widemul(2 * aa[1], aa[3]);
+ accum1 += widemul(2 * a[5], a[7]);
+ accum0 += widemul(aa[2], aa[2]);
+ accum1 += accum0;
+
+ accum0 -= widemul(2 * a[1], a[3]);
+ accum1 += widemul(a[6], a[6]);
+
+ accum2 = widemul(a[0], a[0]);
+ accum1 -= accum2;
+ accum0 += accum2;
+
+ accum0 -= widemul(a[2], a[2]);
+ accum1 += widemul(aa[0], aa[0]);
+ accum0 += widemul(a[4], a[4]);
+
+ c[0] = ((uint64_t)(accum0)) & mask;
+ c[4] = ((uint64_t)(accum1)) & mask;
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+
+ accum2 = widemul(2 * aa[2], aa[3]);
+ accum0 -= widemul(2 * a[2], a[3]);
+ accum1 += widemul(2 * a[6], a[7]);
+
+ accum1 += accum2;
+ accum0 += accum2;
+
+ accum2 = widemul(2 * a[0], a[1]);
+ accum1 += widemul(2 * aa[0], aa[1]);
+ accum0 += widemul(2 * a[4], a[5]);
+
+ accum1 -= accum2;
+ accum0 += accum2;
+
+ c[1] = ((uint64_t)(accum0)) & mask;
+ c[5] = ((uint64_t)(accum1)) & mask;
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+
+ accum2 = widemul(aa[3], aa[3]);
+ accum0 -= widemul(a[3], a[3]);
+ accum1 += widemul(a[7], a[7]);
+
+ accum1 += accum2;
+ accum0 += accum2;
+
+ accum2 = widemul(2 * a[0], a[2]);
+ accum1 += widemul(2 * aa[0], aa[2]);
+ accum0 += widemul(2 * a[4], a[6]);
+
+ accum2 += widemul(a[1], a[1]);
+ accum1 += widemul(aa[1], aa[1]);
+ accum0 += widemul(a[5], a[5]);
+
+ accum1 -= accum2;
+ accum0 += accum2;
+
+ c[2] = ((uint64_t)(accum0)) & mask;
+ c[6] = ((uint64_t)(accum1)) & mask;
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+
+ accum0 += c[3];
+ accum1 += c[7];
+ c[3] = ((uint64_t)(accum0)) & mask;
+ c[7] = ((uint64_t)(accum1)) & mask;
+
+ /* we could almost stop here, but it wouldn't be stable, so... */
+
+ accum0 >>= 56;
+ accum1 >>= 56;
+ c[4] += ((uint64_t)(accum0)) + ((uint64_t)(accum1));
+ c[0] += ((uint64_t)(accum1));
+}
+#endif
diff --git a/crypto/ec/curve448/curve448.c b/crypto/ec/curve448/curve448.c
index 3d4db44564e9..6928d9693ca5 100644
--- a/crypto/ec/curve448/curve448.c
+++ b/crypto/ec/curve448/curve448.c
@@ -2,7 +2,7 @@
* Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -15,6 +15,7 @@
#include "point_448.h"
#include "ed448.h"
+#include "crypto/ecx.h"
#include "curve448_local.h"
#define COFACTOR 4
@@ -54,7 +55,7 @@ static void gf_invert(gf y, const gf x, int assert_nonzero)
}
/** identity = (0,1) */
-const curve448_point_t curve448_point_identity =
+const curve448_point_t ossl_curve448_point_identity =
{ {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}} };
static void point_double_internal(curve448_point_t p, const curve448_point_t q,
@@ -81,7 +82,7 @@ static void point_double_internal(curve448_point_t p, const curve448_point_t q,
gf_mul(p->t, b, d);
}
-void curve448_point_double(curve448_point_t p, const curve448_point_t q)
+void ossl_curve448_point_double(curve448_point_t p, const curve448_point_t q)
{
point_double_internal(p, q, 0);
}
@@ -183,8 +184,9 @@ static void sub_pniels_from_pt(curve448_point_t p, const pniels_t pn,
sub_niels_from_pt(p, pn->n, before_double);
}
-c448_bool_t curve448_point_eq(const curve448_point_t p,
- const curve448_point_t q)
+c448_bool_t
+ossl_curve448_point_eq(const curve448_point_t p,
+ const curve448_point_t q)
{
mask_t succ;
gf a, b;
@@ -197,7 +199,8 @@ c448_bool_t curve448_point_eq(const curve448_point_t p,
return mask_to_bool(succ);
}
-c448_bool_t curve448_point_valid(const curve448_point_t p)
+c448_bool_t
+ossl_curve448_point_valid(const curve448_point_t p)
{
mask_t out;
gf a, b, c;
@@ -224,7 +227,8 @@ static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni,
constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx);
}
-void curve448_precomputed_scalarmul(curve448_point_t out,
+void
+ossl_curve448_precomputed_scalarmul(curve448_point_t out,
const curve448_precomputed_s * table,
const curve448_scalar_t scalar)
{
@@ -233,8 +237,8 @@ void curve448_precomputed_scalarmul(curve448_point_t out,
niels_t ni;
curve448_scalar_t scalar1x;
- curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment);
- curve448_scalar_halve(scalar1x, scalar1x);
+ ossl_curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment);
+ ossl_curve448_scalar_halve(scalar1x, scalar1x);
for (i = s; i > 0; i--) {
if (i != s)
@@ -271,7 +275,8 @@ void curve448_precomputed_scalarmul(curve448_point_t out,
OPENSSL_cleanse(scalar1x, sizeof(scalar1x));
}
-void curve448_point_mul_by_ratio_and_encode_like_eddsa(
+void
+ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(
uint8_t enc[EDDSA_448_PUBLIC_BYTES],
const curve448_point_t p)
{
@@ -315,10 +320,11 @@ void curve448_point_mul_by_ratio_and_encode_like_eddsa(
OPENSSL_cleanse(y, sizeof(y));
OPENSSL_cleanse(z, sizeof(z));
OPENSSL_cleanse(t, sizeof(t));
- curve448_point_destroy(q);
+ ossl_curve448_point_destroy(q);
}
-c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
+c448_error_t
+ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(
curve448_point_t p,
const uint8_t enc[EDDSA_448_PUBLIC_BYTES])
{
@@ -371,14 +377,15 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
}
OPENSSL_cleanse(enc2, sizeof(enc2));
- assert(curve448_point_valid(p) || ~succ);
+ assert(ossl_curve448_point_valid(p) || ~succ);
return c448_succeed_if(mask_to_bool(succ));
}
-c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES],
- const uint8_t base[X_PUBLIC_BYTES],
- const uint8_t scalar[X_PRIVATE_BYTES])
+c448_error_t
+ossl_x448_int(uint8_t out[X_PUBLIC_BYTES],
+ const uint8_t base[X_PUBLIC_BYTES],
+ const uint8_t scalar[X_PRIVATE_BYTES])
{
gf x1, x2, z2, x3, z3, t1, t2;
int t;
@@ -455,7 +462,8 @@ c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES],
return c448_succeed_if(mask_to_bool(nz));
}
-void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t
+void
+ossl_curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t
out[X_PUBLIC_BYTES],
const curve448_point_t p)
{
@@ -466,11 +474,11 @@ void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t
gf_mul(q->z, q->t, q->y); /* y/x */
gf_sqr(q->y, q->z); /* (y/x)^2 */
gf_serialize(out, q->y, 1);
- curve448_point_destroy(q);
+ ossl_curve448_point_destroy(q);
}
-void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES],
- const uint8_t scalar[X_PRIVATE_BYTES])
+void ossl_x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES],
+ const uint8_t scalar[X_PRIVATE_BYTES])
{
/* Scalar conditioning */
uint8_t scalar2[X_PRIVATE_BYTES];
@@ -484,15 +492,16 @@ void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES],
scalar2[X_PRIVATE_BYTES - 1] &= ~((0u - 1u) << ((X_PRIVATE_BITS + 7) % 8));
scalar2[X_PRIVATE_BYTES - 1] |= 1 << ((X_PRIVATE_BITS + 7) % 8);
- curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2));
+ ossl_curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2));
/* Compensate for the encoding ratio */
for (i = 1; i < X448_ENCODE_RATIO; i <<= 1)
- curve448_scalar_halve(the_scalar, the_scalar);
+ ossl_curve448_scalar_halve(the_scalar, the_scalar);
- curve448_precomputed_scalarmul(p, curve448_precomputed_base, the_scalar);
- curve448_point_mul_by_ratio_and_encode_like_x448(out, p);
- curve448_point_destroy(p);
+ ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base,
+ the_scalar);
+ ossl_curve448_point_mul_by_ratio_and_encode_like_x448(out, p);
+ ossl_curve448_point_destroy(p);
}
/* Control for variable-time scalar multiply algorithms. */
@@ -501,9 +510,9 @@ struct smvt_control {
};
#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))
-# define NUMTRAILINGZEROS __builtin_ctz
+# define NUMTRAILINGZEROS __builtin_ctz
#else
-# define NUMTRAILINGZEROS numtrailingzeros
+# define NUMTRAILINGZEROS numtrailingzeros
static uint32_t numtrailingzeros(uint32_t i)
{
uint32_t tmp;
@@ -610,7 +619,7 @@ static void prepare_wnaf_table(pniels_t * output,
if (tbits == 0)
return;
- curve448_point_double(tmp, working);
+ ossl_curve448_point_double(tmp, working);
pt_to_pniels(twop, tmp);
add_pniels_to_pt(tmp, output[0], 0);
@@ -621,11 +630,12 @@ static void prepare_wnaf_table(pniels_t * output,
pt_to_pniels(output[i], tmp);
}
- curve448_point_destroy(tmp);
+ ossl_curve448_point_destroy(tmp);
OPENSSL_cleanse(twop, sizeof(twop));
}
-void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
+void
+ossl_curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
const curve448_scalar_t scalar1,
const curve448_point_t base2,
const curve448_scalar_t scalar2)
@@ -645,7 +655,7 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
i = control_var[0].power;
if (i < 0) {
- curve448_point_copy(combo, curve448_point_identity);
+ curve448_point_copy(combo, ossl_curve448_point_identity);
return;
}
if (i > control_pre[0].power) {
@@ -653,13 +663,14 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
contv++;
} else if (i == control_pre[0].power && i >= 0) {
pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);
- add_niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1],
+ add_niels_to_pt(combo,
+ ossl_curve448_wnaf_base[control_pre[0].addend >> 1],
i);
contv++;
contp++;
} else {
i = control_pre[0].power;
- niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1]);
+ niels_to_pt(combo, ossl_curve448_wnaf_base[control_pre[0].addend >> 1]);
contp++;
}
@@ -688,11 +699,11 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
if (control_pre[contp].addend > 0)
add_niels_to_pt(combo,
- curve448_wnaf_base[control_pre[contp].addend
+ ossl_curve448_wnaf_base[control_pre[contp].addend
>> 1], i);
else
sub_niels_from_pt(combo,
- curve448_wnaf_base[(-control_pre
+ ossl_curve448_wnaf_base[(-control_pre
[contp].addend) >> 1], i);
contp++;
}
@@ -709,20 +720,20 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
(void)ncb_pre;
}
-void curve448_point_destroy(curve448_point_t point)
+void ossl_curve448_point_destroy(curve448_point_t point)
{
OPENSSL_cleanse(point, sizeof(curve448_point_t));
}
-int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],
- const uint8_t peer_public_value[56])
+int ossl_x448(uint8_t out_shared_key[56], const uint8_t private_key[56],
+ const uint8_t peer_public_value[56])
{
- return x448_int(out_shared_key, peer_public_value, private_key)
+ return ossl_x448_int(out_shared_key, peer_public_value, private_key)
== C448_SUCCESS;
}
-void X448_public_from_private(uint8_t out_public_value[56],
- const uint8_t private_key[56])
+void ossl_x448_public_from_private(uint8_t out_public_value[56],
+ const uint8_t private_key[56])
{
- x448_derive_public_key(out_public_value, private_key);
+ ossl_x448_derive_public_key(out_public_value, private_key);
}
diff --git a/crypto/ec/curve448/curve448_local.h b/crypto/ec/curve448/curve448_local.h
index b27770661f89..3410f091a655 100644
--- a/crypto/ec/curve448/curve448_local.h
+++ b/crypto/ec/curve448/curve448_local.h
@@ -1,7 +1,7 @@
/*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -10,29 +10,15 @@
# define OSSL_CRYPTO_EC_CURVE448_LOCAL_H
# include "curve448utils.h"
-int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],
- const uint8_t peer_public_value[56]);
+int
+ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
+ const uint8_t public_key[57], const uint8_t private_key[57],
+ const uint8_t *context, size_t context_len, const char *propq);
-void X448_public_from_private(uint8_t out_public_value[56],
- const uint8_t private_key[56]);
-
-int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t public_key[57], const uint8_t private_key[57],
- const uint8_t *context, size_t context_len);
-
-int ED448_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[114], const uint8_t public_key[57],
- const uint8_t *context, size_t context_len);
-
-int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
- const uint8_t public_key[57], const uint8_t private_key[57],
- const uint8_t *context, size_t context_len);
-
-int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
- const uint8_t public_key[57], const uint8_t *context,
- size_t context_len);
-
-int ED448_public_from_private(uint8_t out_public_key[57],
- const uint8_t private_key[57]);
+int
+ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64],
+ const uint8_t signature[114], const uint8_t public_key[57],
+ const uint8_t *context, size_t context_len,
+ const char *propq);
#endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */
diff --git a/crypto/ec/curve448/curve448_tables.c b/crypto/ec/curve448/curve448_tables.c
index 9ef29769e3b3..0c6f626b3e6e 100644
--- a/crypto/ec/curve448/curve448_tables.c
+++ b/crypto/ec/curve448/curve448_tables.c
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -1058,7 +1058,7 @@ static const curve448_precomputed_s curve448_precomputed_base_table = {
}}
}
};
-const struct curve448_precomputed_s *curve448_precomputed_base
+const struct curve448_precomputed_s *ossl_curve448_precomputed_base
= &curve448_precomputed_base_table;
static const niels_t curve448_wnaf_base_table[32] = {
@@ -1480,4 +1480,4 @@ static const niels_t curve448_wnaf_base_table[32] = {
0x001979c0df237316ULL, 0x00501e953a919b87ULL)},
}}
};
-const niels_t *curve448_wnaf_base = curve448_wnaf_base_table;
+const niels_t *ossl_curve448_wnaf_base = curve448_wnaf_base_table;
diff --git a/crypto/ec/curve448/curve448utils.h b/crypto/ec/curve448/curve448utils.h
index 86c258e745e4..664c6e6ff306 100644
--- a/crypto/ec/curve448/curve448utils.h
+++ b/crypto/ec/curve448/curve448utils.h
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -15,6 +15,8 @@
# include <openssl/e_os2.h>
+# include "internal/numbers.h"
+
/*
* Internal word types. Somewhat tricky. This could be decided separately per
* platform. However, the structs do need to be all the same size and
@@ -41,9 +43,9 @@ typedef int64_t c448_sword_t;
/* "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */
typedef uint64_t c448_bool_t;
/* Double-word size for internal computations */
-typedef __uint128_t c448_dword_t;
+typedef uint128_t c448_dword_t;
/* Signed double-word size for internal computations */
-typedef __int128_t c448_dsword_t;
+typedef int128_t c448_dsword_t;
# elif C448_WORD_BITS == 32
/* Word size for internal computations */
typedef uint32_t c448_word_t;
diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h
index c1e5c2832f9b..00b2bae580ba 100644
--- a/crypto/ec/curve448/ed448.h
+++ b/crypto/ec/curve448/ed448.h
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -37,9 +37,12 @@
* pubkey (out): The public key.
* privkey (in): The private key.
*/
-c448_error_t c448_ed448_derive_public_key(
- uint8_t pubkey [EDDSA_448_PUBLIC_BYTES],
- const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]);
+c448_error_t
+ossl_c448_ed448_derive_public_key(
+ OSSL_LIB_CTX *ctx,
+ uint8_t pubkey [EDDSA_448_PUBLIC_BYTES],
+ const uint8_t privkey [EDDSA_448_PRIVATE_BYTES],
+ const char *propq);
/*
* EdDSA signing.
@@ -58,13 +61,15 @@ c448_error_t c448_ed448_derive_public_key(
* non-prehashed messages, at least without some very careful protocol-level
* disambiguation. For Ed448 it is safe.
*/
-c448_error_t c448_ed448_sign(
- uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
- const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
- const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t *message, size_t message_len,
- uint8_t prehashed, const uint8_t *context,
- size_t context_len);
+c448_error_t
+ossl_c448_ed448_sign(OSSL_LIB_CTX *ctx,
+ uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
+ const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
+ const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
+ const uint8_t *message, size_t message_len,
+ uint8_t prehashed, const uint8_t *context,
+ size_t context_len,
+ const char *propq);
/*
* EdDSA signing with prehash.
@@ -82,13 +87,15 @@ c448_error_t c448_ed448_sign(
* non-prehashed messages, at least without some very careful protocol-level
* disambiguation. For Ed448 it is safe.
*/
-c448_error_t c448_ed448_sign_prehash(
- uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
- const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
- const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t hash[64],
- const uint8_t *context,
- size_t context_len);
+c448_error_t
+ossl_c448_ed448_sign_prehash(OSSL_LIB_CTX *ctx,
+ uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
+ const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
+ const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
+ const uint8_t hash[64],
+ const uint8_t *context,
+ size_t context_len,
+ const char *propq);
/*
* EdDSA signature verification.
@@ -108,13 +115,16 @@ c448_error_t c448_ed448_sign_prehash(
* non-prehashed messages, at least without some very careful protocol-level
* disambiguation. For Ed448 it is safe.
*/
-c448_error_t c448_ed448_verify(const uint8_t
- signature[EDDSA_448_SIGNATURE_BYTES],
- const uint8_t
- pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t *message, size_t message_len,
- uint8_t prehashed, const uint8_t *context,
- uint8_t context_len);
+c448_error_t
+ossl_c448_ed448_verify(OSSL_LIB_CTX *ctx,
+ const uint8_t
+ signature[EDDSA_448_SIGNATURE_BYTES],
+ const uint8_t
+ pubkey[EDDSA_448_PUBLIC_BYTES],
+ const uint8_t *message, size_t message_len,
+ uint8_t prehashed, const uint8_t *context,
+ uint8_t context_len,
+ const char *propq);
/*
* EdDSA signature verification.
@@ -133,12 +143,15 @@ c448_error_t c448_ed448_verify(const uint8_t
* non-prehashed messages, at least without some very careful protocol-level
* disambiguation. For Ed448 it is safe.
*/
-c448_error_t c448_ed448_verify_prehash(
- const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
- const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t hash[64],
- const uint8_t *context,
- uint8_t context_len);
+c448_error_t
+ossl_c448_ed448_verify_prehash(
+ OSSL_LIB_CTX *ctx,
+ const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
+ const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
+ const uint8_t hash[64],
+ const uint8_t *context,
+ uint8_t context_len,
+ const char *propq);
/*
* EdDSA point encoding. Used internally, exposed externally.
@@ -163,7 +176,8 @@ c448_error_t c448_ed448_verify_prehash(
* enc (out): The encoded point.
* p (in): The point.
*/
-void curve448_point_mul_by_ratio_and_encode_like_eddsa(
+void
+ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(
uint8_t enc [EDDSA_448_PUBLIC_BYTES],
const curve448_point_t p);
@@ -176,7 +190,8 @@ void curve448_point_mul_by_ratio_and_encode_like_eddsa(
* enc (out): The encoded point.
* p (in): The point.
*/
-c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
+c448_error_t
+ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(
curve448_point_t p,
const uint8_t enc[EDDSA_448_PUBLIC_BYTES]);
@@ -188,8 +203,11 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
* x (out): The ECDH private key as in RFC7748
* ed (in): The EdDSA private key
*/
-c448_error_t c448_ed448_convert_private_key_to_x448(
- uint8_t x[X448_PRIVATE_BYTES],
- const uint8_t ed[EDDSA_448_PRIVATE_BYTES]);
+c448_error_t
+ossl_c448_ed448_convert_private_key_to_x448(
+ OSSL_LIB_CTX *ctx,
+ uint8_t x[X448_PRIVATE_BYTES],
+ const uint8_t ed[EDDSA_448_PRIVATE_BYTES],
+ const char *propq);
#endif /* OSSL_CRYPTO_EC_CURVE448_ED448_H */
diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c
index 82741f543549..6648692ff395 100644
--- a/crypto/ec/curve448/eddsa.c
+++ b/crypto/ec/curve448/eddsa.c
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -12,6 +12,7 @@
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
+#include "crypto/ecx.h"
#include "curve448_local.h"
#include "word.h"
#include "ed448.h"
@@ -19,23 +20,31 @@
#define COFACTOR 4
-static c448_error_t oneshot_hash(uint8_t *out, size_t outlen,
- const uint8_t *in, size_t inlen)
+static c448_error_t oneshot_hash(OSSL_LIB_CTX *ctx, uint8_t *out, size_t outlen,
+ const uint8_t *in, size_t inlen,
+ const char *propq)
{
EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
+ EVP_MD *shake256 = NULL;
+ c448_error_t ret = C448_FAILURE;
if (hashctx == NULL)
return C448_FAILURE;
- if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
+ shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq);
+ if (shake256 == NULL)
+ goto err;
+
+ if (!EVP_DigestInit_ex(hashctx, shake256, NULL)
|| !EVP_DigestUpdate(hashctx, in, inlen)
- || !EVP_DigestFinalXOF(hashctx, out, outlen)) {
- EVP_MD_CTX_free(hashctx);
- return C448_FAILURE;
- }
+ || !EVP_DigestFinalXOF(hashctx, out, outlen))
+ goto err;
+ ret = C448_SUCCESS;
+ err:
EVP_MD_CTX_free(hashctx);
- return C448_SUCCESS;
+ EVP_MD_free(shake256);
+ return ret;
}
static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
@@ -45,10 +54,12 @@ static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
}
-static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
+static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx,
+ uint8_t prehashed,
uint8_t for_prehash,
const uint8_t *context,
- size_t context_len)
+ size_t context_len,
+ const char *propq)
{
#ifdef CHARSET_EBCDIC
const char dom_s[] = {0x53, 0x69, 0x67, 0x45,
@@ -57,6 +68,7 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
const char dom_s[] = "SigEd448";
#endif
uint8_t dom[2];
+ EVP_MD *shake256 = NULL;
if (context_len > UINT8_MAX)
return C448_FAILURE;
@@ -65,29 +77,42 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
- (for_prehash == 0 ? 1 : 0));
dom[1] = (uint8_t)context_len;
- if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
+ shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq);
+ if (shake256 == NULL)
+ return C448_FAILURE;
+
+ if (!EVP_DigestInit_ex(hashctx, shake256, NULL)
|| !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
|| !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
- || !EVP_DigestUpdate(hashctx, context, context_len))
+ || !EVP_DigestUpdate(hashctx, context, context_len)) {
+ EVP_MD_free(shake256);
return C448_FAILURE;
+ }
+ EVP_MD_free(shake256);
return C448_SUCCESS;
}
/* In this file because it uses the hash */
-c448_error_t c448_ed448_convert_private_key_to_x448(
+c448_error_t
+ossl_c448_ed448_convert_private_key_to_x448(
+ OSSL_LIB_CTX *ctx,
uint8_t x[X448_PRIVATE_BYTES],
- const uint8_t ed [EDDSA_448_PRIVATE_BYTES])
+ const uint8_t ed [EDDSA_448_PRIVATE_BYTES],
+ const char *propq)
{
/* pass the private key through oneshot_hash function */
/* and keep the first X448_PRIVATE_BYTES bytes */
- return oneshot_hash(x, X448_PRIVATE_BYTES, ed,
- EDDSA_448_PRIVATE_BYTES);
+ return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed,
+ EDDSA_448_PRIVATE_BYTES, propq);
}
-c448_error_t c448_ed448_derive_public_key(
+c448_error_t
+ossl_c448_ed448_derive_public_key(
+ OSSL_LIB_CTX *ctx,
uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t privkey[EDDSA_448_PRIVATE_BYTES])
+ const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
+ const char *propq)
{
/* only this much used for keygen */
uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES];
@@ -95,14 +120,16 @@ c448_error_t c448_ed448_derive_public_key(
unsigned int c;
curve448_point_t p;
- if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey,
- EDDSA_448_PRIVATE_BYTES))
+ if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser),
+ privkey,
+ EDDSA_448_PRIVATE_BYTES,
+ propq))
return C448_FAILURE;
clamp(secret_scalar_ser);
- curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
- sizeof(secret_scalar_ser));
+ ossl_curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
+ sizeof(secret_scalar_ser));
/*
* Since we are going to mul_by_cofactor during encoding, divide by it
@@ -113,27 +140,29 @@ c448_error_t c448_ed448_derive_public_key(
* we might start at 2 instead of 1.
*/
for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
- curve448_scalar_halve(secret_scalar, secret_scalar);
+ ossl_curve448_scalar_halve(secret_scalar, secret_scalar);
- curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar);
+ ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base,
+ secret_scalar);
- curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
+ ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
/* Cleanup */
- curve448_scalar_destroy(secret_scalar);
- curve448_point_destroy(p);
+ ossl_curve448_scalar_destroy(secret_scalar);
+ ossl_curve448_point_destroy(p);
OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
return C448_SUCCESS;
}
-c448_error_t c448_ed448_sign(
- uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
- const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
- const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
- const uint8_t *message, size_t message_len,
- uint8_t prehashed, const uint8_t *context,
- size_t context_len)
+c448_error_t
+ossl_c448_ed448_sign(OSSL_LIB_CTX *ctx,
+ uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
+ const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
+ const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
+ const uint8_t *message, size_t message_len,
+ uint8_t prehashed, const uint8_t *context,
+ size_t context_len, const char *propq)
{
curve448_scalar_t secret_scalar;
EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
@@ -148,20 +177,21 @@ c448_error_t c448_ed448_sign(
{
/*
- * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialised
+ * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialized
* secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed.
*/
uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2];
- if (!oneshot_hash(expanded, sizeof(expanded), privkey,
- EDDSA_448_PRIVATE_BYTES))
+ if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey,
+ EDDSA_448_PRIVATE_BYTES, propq))
goto err;
clamp(expanded);
- curve448_scalar_decode_long(secret_scalar, expanded,
- EDDSA_448_PRIVATE_BYTES);
+ ossl_curve448_scalar_decode_long(secret_scalar, expanded,
+ EDDSA_448_PRIVATE_BYTES);
/* Hash to create the nonce */
- if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
+ if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context,
+ context_len, propq)
|| !EVP_DigestUpdate(hashctx,
expanded + EDDSA_448_PRIVATE_BYTES,
EDDSA_448_PRIVATE_BYTES)
@@ -178,7 +208,7 @@ c448_error_t c448_ed448_sign(
if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
goto err;
- curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
+ ossl_curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
OPENSSL_cleanse(nonce, sizeof(nonce));
}
@@ -187,44 +217,45 @@ c448_error_t c448_ed448_sign(
curve448_scalar_t nonce_scalar_2;
curve448_point_t p;
- curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
+ ossl_curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
- curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
+ ossl_curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
- curve448_precomputed_scalarmul(p, curve448_precomputed_base,
- nonce_scalar_2);
- curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
- curve448_point_destroy(p);
- curve448_scalar_destroy(nonce_scalar_2);
+ ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base,
+ nonce_scalar_2);
+ ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
+ ossl_curve448_point_destroy(p);
+ ossl_curve448_scalar_destroy(nonce_scalar_2);
}
{
uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
/* Compute the challenge */
- if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
+ if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len,
+ propq)
|| !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
|| !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
|| !EVP_DigestUpdate(hashctx, message, message_len)
|| !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
goto err;
- curve448_scalar_decode_long(challenge_scalar, challenge,
- sizeof(challenge));
+ ossl_curve448_scalar_decode_long(challenge_scalar, challenge,
+ sizeof(challenge));
OPENSSL_cleanse(challenge, sizeof(challenge));
}
- curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
- curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
+ ossl_curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
+ ossl_curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES);
memcpy(signature, nonce_point, sizeof(nonce_point));
- curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
- challenge_scalar);
+ ossl_curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
+ challenge_scalar);
- curve448_scalar_destroy(secret_scalar);
- curve448_scalar_destroy(nonce_scalar);
- curve448_scalar_destroy(challenge_scalar);
+ ossl_curve448_scalar_destroy(secret_scalar);
+ ossl_curve448_scalar_destroy(nonce_scalar);
+ ossl_curve448_scalar_destroy(challenge_scalar);
ret = C448_SUCCESS;
err:
@@ -232,23 +263,27 @@ c448_error_t c448_ed448_sign(
return ret;
}
-c448_error_t c448_ed448_sign_prehash(
+c448_error_t
+ossl_c448_ed448_sign_prehash(
+ OSSL_LIB_CTX *ctx,
uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
const uint8_t hash[64], const uint8_t *context,
- size_t context_len)
+ size_t context_len, const char *propq)
{
- return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context,
- context_len);
+ return ossl_c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1,
+ context, context_len, propq);
}
-c448_error_t c448_ed448_verify(
+c448_error_t
+ossl_c448_ed448_verify(
+ OSSL_LIB_CTX *ctx,
const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
const uint8_t *message, size_t message_len,
uint8_t prehashed, const uint8_t *context,
- uint8_t context_len)
+ uint8_t context_len, const char *propq)
{
curve448_point_t pk_point, r_point;
c448_error_t error;
@@ -280,13 +315,13 @@ c448_error_t c448_ed448_verify(
return C448_FAILURE;
error =
- curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
+ ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
if (C448_SUCCESS != error)
return error;
error =
- curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
+ ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
if (C448_SUCCESS != error)
return error;
@@ -296,8 +331,8 @@ c448_error_t c448_ed448_verify(
uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
if (hashctx == NULL
- || !hash_init_with_dom(hashctx, prehashed, 0, context,
- context_len)
+ || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context,
+ context_len, propq)
|| !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES)
|| !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
|| !EVP_DigestUpdate(hashctx, message, message_len)
@@ -307,71 +342,82 @@ c448_error_t c448_ed448_verify(
}
EVP_MD_CTX_free(hashctx);
- curve448_scalar_decode_long(challenge_scalar, challenge,
- sizeof(challenge));
+ ossl_curve448_scalar_decode_long(challenge_scalar, challenge,
+ sizeof(challenge));
OPENSSL_cleanse(challenge, sizeof(challenge));
}
- curve448_scalar_sub(challenge_scalar, curve448_scalar_zero,
- challenge_scalar);
+ ossl_curve448_scalar_sub(challenge_scalar, ossl_curve448_scalar_zero,
+ challenge_scalar);
- curve448_scalar_decode_long(response_scalar,
- &signature[EDDSA_448_PUBLIC_BYTES],
- EDDSA_448_PRIVATE_BYTES);
+ ossl_curve448_scalar_decode_long(response_scalar,
+ &signature[EDDSA_448_PUBLIC_BYTES],
+ EDDSA_448_PRIVATE_BYTES);
/* pk_point = -c(x(P)) + (cx + k)G = kG */
- curve448_base_double_scalarmul_non_secret(pk_point,
- response_scalar,
- pk_point, challenge_scalar);
- return c448_succeed_if(curve448_point_eq(pk_point, r_point));
+ ossl_curve448_base_double_scalarmul_non_secret(pk_point,
+ response_scalar,
+ pk_point, challenge_scalar);
+ return c448_succeed_if(ossl_curve448_point_eq(pk_point, r_point));
}
-c448_error_t c448_ed448_verify_prehash(
+c448_error_t
+ossl_c448_ed448_verify_prehash(
+ OSSL_LIB_CTX *ctx,
const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
const uint8_t hash[64], const uint8_t *context,
- uint8_t context_len)
+ uint8_t context_len, const char *propq)
{
- return c448_ed448_verify(signature, pubkey, hash, 64, 1, context,
- context_len);
+ return ossl_c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context,
+ context_len, propq);
}
-int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t public_key[57], const uint8_t private_key[57],
- const uint8_t *context, size_t context_len)
+int
+ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message,
+ size_t message_len, const uint8_t public_key[57],
+ const uint8_t private_key[57], const uint8_t *context,
+ size_t context_len, const char *propq)
{
- return c448_ed448_sign(out_sig, private_key, public_key, message,
- message_len, 0, context, context_len)
- == C448_SUCCESS;
+ return ossl_c448_ed448_sign(ctx, out_sig, private_key, public_key, message,
+ message_len, 0, context, context_len,
+ propq) == C448_SUCCESS;
}
-int ED448_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[114], const uint8_t public_key[57],
- const uint8_t *context, size_t context_len)
+int
+ossl_ed448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len,
+ const uint8_t signature[114], const uint8_t public_key[57],
+ const uint8_t *context, size_t context_len, const char *propq)
{
- return c448_ed448_verify(signature, public_key, message, message_len, 0,
- context, (uint8_t)context_len) == C448_SUCCESS;
+ return ossl_c448_ed448_verify(ctx, signature, public_key, message,
+ message_len, 0, context, (uint8_t)context_len,
+ propq) == C448_SUCCESS;
}
-int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
- const uint8_t public_key[57], const uint8_t private_key[57],
- const uint8_t *context, size_t context_len)
+int
+ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
+ const uint8_t public_key[57], const uint8_t private_key[57],
+ const uint8_t *context, size_t context_len, const char *propq)
{
- return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash,
- context, context_len) == C448_SUCCESS;
-
+ return ossl_c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key,
+ hash, context, context_len,
+ propq) == C448_SUCCESS;
}
-int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
- const uint8_t public_key[57], const uint8_t *context,
- size_t context_len)
+int
+ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64],
+ const uint8_t signature[114], const uint8_t public_key[57],
+ const uint8_t *context, size_t context_len,
+ const char *propq)
{
- return c448_ed448_verify_prehash(signature, public_key, hash, context,
- (uint8_t)context_len) == C448_SUCCESS;
+ return ossl_c448_ed448_verify_prehash(ctx, signature, public_key, hash,
+ context, (uint8_t)context_len,
+ propq) == C448_SUCCESS;
}
-int ED448_public_from_private(uint8_t out_public_key[57],
- const uint8_t private_key[57])
+int
+ossl_ed448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57],
+ const uint8_t private_key[57], const char *propq)
{
- return c448_ed448_derive_public_key(out_public_key, private_key)
- == C448_SUCCESS;
+ return ossl_c448_ed448_derive_public_key(ctx, out_public_key, private_key,
+ propq) == C448_SUCCESS;
}
diff --git a/crypto/ec/curve448/f_generic.c b/crypto/ec/curve448/f_generic.c
index 09d08165e250..4c571810d3af 100644
--- a/crypto/ec/curve448/f_generic.c
+++ b/crypto/ec/curve448/f_generic.c
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -18,7 +18,7 @@ static const gf MODULUS = {
};
/* Serialize to wire format. */
-void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_hibit)
+void gf_serialize(uint8_t *serial, const gf x, int with_hibit)
{
unsigned int j = 0, fill = 0;
dword_t buffer = 0;
diff --git a/crypto/ec/curve448/field.h b/crypto/ec/curve448/field.h
index 4e4eda664f78..e1c633378950 100644
--- a/crypto/ec/curve448/field.h
+++ b/crypto/ec/curve448/field.h
@@ -2,7 +2,7 @@
* Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2014 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -62,14 +62,19 @@ mask_t gf_eq(const gf x, const gf y);
mask_t gf_lobit(const gf x);
mask_t gf_hibit(const gf x);
-void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_highbit);
+void gf_serialize(uint8_t *serial, const gf x, int with_highbit);
mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit,
uint8_t hi_nmask);
-# include "f_impl.h" /* Bring in the inline implementations */
# define LIMBPERM(i) (i)
-# define LIMB_MASK(i) (((1)<<LIMB_PLACE_VALUE(i))-1)
+# if (ARCH_WORD_BITS == 32)
+# include "arch_32/f_impl.h" /* Bring in the inline implementations */
+# define LIMB_MASK(i) (((1)<<LIMB_PLACE_VALUE(i))-1)
+# elif (ARCH_WORD_BITS == 64)
+# include "arch_64/f_impl.h" /* Bring in the inline implementations */
+# define LIMB_MASK(i) (((1ULL)<<LIMB_PLACE_VALUE(i))-1)
+# endif
static const gf ZERO = {{{0}}}, ONE = {{{1}}};
diff --git a/crypto/ec/curve448/point_448.h b/crypto/ec/curve448/point_448.h
index 93e715fd9c8d..e67ea68044eb 100644
--- a/crypto/ec/curve448/point_448.h
+++ b/crypto/ec/curve448/point_448.h
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -69,17 +69,17 @@ typedef struct curve448_scalar_s {
} curve448_scalar_t[1];
/* A scalar equal to 1. */
-extern const curve448_scalar_t curve448_scalar_one;
+extern const curve448_scalar_t ossl_curve448_scalar_one;
/* A scalar equal to 0. */
-extern const curve448_scalar_t curve448_scalar_zero;
+extern const curve448_scalar_t ossl_curve448_scalar_zero;
/* The identity point on the curve. */
-extern const curve448_point_t curve448_point_identity;
+extern const curve448_point_t ossl_curve448_point_identity;
/* Precomputed table for the base point on the curve. */
-extern const struct curve448_precomputed_s *curve448_precomputed_base;
-extern const niels_t *curve448_wnaf_base;
+extern const struct curve448_precomputed_s *ossl_curve448_precomputed_base;
+extern const niels_t *ossl_curve448_wnaf_base;
/*
* Read a scalar from wire format or from bytes.
@@ -92,8 +92,9 @@ extern const niels_t *curve448_wnaf_base;
* C448_FAILURE: The scalar was greater than the modulus, and has been reduced
* modulo that modulus.
*/
-c448_error_t curve448_scalar_decode(curve448_scalar_t out,
- const unsigned char ser[C448_SCALAR_BYTES]);
+c448_error_t
+ossl_curve448_scalar_decode(curve448_scalar_t out,
+ const unsigned char ser[C448_SCALAR_BYTES]);
/*
* Read a scalar from wire format or from bytes. Reduces mod scalar prime.
@@ -102,7 +103,8 @@ c448_error_t curve448_scalar_decode(curve448_scalar_t out,
* ser_len (in): Length of serialized form.
* out (out): Deserialized form.
*/
-void curve448_scalar_decode_long(curve448_scalar_t out,
+void
+ossl_curve448_scalar_decode_long(curve448_scalar_t out,
const unsigned char *ser, size_t ser_len);
/*
@@ -111,7 +113,8 @@ void curve448_scalar_decode_long(curve448_scalar_t out,
* ser (out): Serialized form of a scalar.
* s (in): Deserialized scalar.
*/
-void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
+void
+ossl_curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
const curve448_scalar_t s);
/*
@@ -121,7 +124,8 @@ void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
* b (in): Another scalar.
* out (out): a+b.
*/
-void curve448_scalar_add(curve448_scalar_t out,
+void
+ossl_curve448_scalar_add(curve448_scalar_t out,
const curve448_scalar_t a, const curve448_scalar_t b);
/*
@@ -130,7 +134,8 @@ void curve448_scalar_add(curve448_scalar_t out,
* b (in): Another scalar.
* out (out): a-b.
*/
-void curve448_scalar_sub(curve448_scalar_t out,
+void
+ossl_curve448_scalar_sub(curve448_scalar_t out,
const curve448_scalar_t a, const curve448_scalar_t b);
/*
@@ -140,7 +145,8 @@ void curve448_scalar_sub(curve448_scalar_t out,
* b (in): Another scalar.
* out (out): a*b.
*/
-void curve448_scalar_mul(curve448_scalar_t out,
+void
+ossl_curve448_scalar_mul(curve448_scalar_t out,
const curve448_scalar_t a, const curve448_scalar_t b);
/*
@@ -149,7 +155,8 @@ void curve448_scalar_mul(curve448_scalar_t out,
* a (in): A scalar.
* out (out): a/2.
*/
-void curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a);
+void
+ossl_curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a);
/*
* Copy a scalar. The scalars may alias each other, in which case this
@@ -188,8 +195,9 @@ static ossl_inline void curve448_point_copy(curve448_point_t a,
* C448_TRUE: The points are equal.
* C448_FALSE: The points are not equal.
*/
-__owur c448_bool_t curve448_point_eq(const curve448_point_t a,
- const curve448_point_t b);
+__owur c448_bool_t
+ossl_curve448_point_eq(const curve448_point_t a,
+ const curve448_point_t b);
/*
* Double a point. Equivalent to curve448_point_add(two_a,a,a), but potentially
@@ -198,7 +206,8 @@ __owur c448_bool_t curve448_point_eq(const curve448_point_t a,
* two_a (out): The sum a+a.
* a (in): A point.
*/
-void curve448_point_double(curve448_point_t two_a, const curve448_point_t a);
+void
+ossl_curve448_point_double(curve448_point_t two_a, const curve448_point_t a);
/*
* RFC 7748 Diffie-Hellman scalarmul. This function uses a different
@@ -213,9 +222,10 @@ void curve448_point_double(curve448_point_t two_a, const curve448_point_t a);
* C448_FAILURE: The scalarmul didn't succeed, because the base point is in a
* small subgroup.
*/
-__owur c448_error_t x448_int(uint8_t out[X448_PUBLIC_BYTES],
- const uint8_t base[X448_PUBLIC_BYTES],
- const uint8_t scalar[X448_PRIVATE_BYTES]);
+__owur c448_error_t
+ossl_x448_int(uint8_t out[X448_PUBLIC_BYTES],
+ const uint8_t base[X448_PUBLIC_BYTES],
+ const uint8_t scalar[X448_PRIVATE_BYTES]);
/*
* Multiply a point by X448_ENCODE_RATIO, then encode it like RFC 7748.
@@ -236,7 +246,8 @@ __owur c448_error_t x448_int(uint8_t out[X448_PUBLIC_BYTES],
* out (out): The scaled and encoded point.
* p (in): The point to be scaled and encoded.
*/
-void curve448_point_mul_by_ratio_and_encode_like_x448(
+void
+ossl_curve448_point_mul_by_ratio_and_encode_like_x448(
uint8_t out[X448_PUBLIC_BYTES],
const curve448_point_t p);
@@ -247,7 +258,8 @@ void curve448_point_mul_by_ratio_and_encode_like_x448(
* out (out): The scaled point base*scalar
* scalar (in): The scalar to multiply by.
*/
-void x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES],
+void
+ossl_x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES],
const uint8_t scalar[X448_PRIVATE_BYTES]);
/*
@@ -257,7 +269,8 @@ void x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES],
* base (in): The point to be scaled.
* scalar (in): The scalar to multiply by.
*/
-void curve448_precomputed_scalarmul(curve448_point_t scaled,
+void
+ossl_curve448_precomputed_scalarmul(curve448_point_t scaled,
const curve448_precomputed_s * base,
const curve448_scalar_t scalar);
@@ -276,7 +289,8 @@ void curve448_precomputed_scalarmul(curve448_point_t scaled,
* Warning: This function takes variable time, and may leak the scalars used.
* It is designed for signature verification.
*/
-void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
+void
+ossl_curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
const curve448_scalar_t scalar1,
const curve448_point_t base2,
const curve448_scalar_t scalar2);
@@ -290,12 +304,13 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
* C448_TRUE The point is valid.
* C448_FALSE The point is invalid.
*/
-__owur c448_bool_t curve448_point_valid(const curve448_point_t to_test);
+__owur c448_bool_t
+ossl_curve448_point_valid(const curve448_point_t to_test);
/* Overwrite scalar with zeros. */
-void curve448_scalar_destroy(curve448_scalar_t scalar);
+void ossl_curve448_scalar_destroy(curve448_scalar_t scalar);
/* Overwrite point with zeros. */
-void curve448_point_destroy(curve448_point_t point);
+void ossl_curve448_point_destroy(curve448_point_t point);
#endif /* OSSL_CRYPTO_EC_CURVE448_POINT_448_H */
diff --git a/crypto/ec/curve448/scalar.c b/crypto/ec/curve448/scalar.c
index 347794bbac38..99c0d83db13b 100644
--- a/crypto/ec/curve448/scalar.c
+++ b/crypto/ec/curve448/scalar.c
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2016 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -38,8 +38,8 @@ static const curve448_scalar_t sc_p = {
#define WBITS C448_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */
-const curve448_scalar_t curve448_scalar_one = {{{1}}};
-const curve448_scalar_t curve448_scalar_zero = {{{0}}};
+const curve448_scalar_t ossl_curve448_scalar_one = {{{1}}};
+const curve448_scalar_t ossl_curve448_scalar_zero = {{{0}}};
/*
* {extra,accum} - sub +? p
@@ -106,20 +106,22 @@ static void sc_montmul(curve448_scalar_t out, const curve448_scalar_t a,
sc_subx(out, accum, sc_p, sc_p, hi_carry);
}
-void curve448_scalar_mul(curve448_scalar_t out, const curve448_scalar_t a,
- const curve448_scalar_t b)
+void ossl_curve448_scalar_mul(curve448_scalar_t out, const curve448_scalar_t a,
+ const curve448_scalar_t b)
{
sc_montmul(out, a, b);
sc_montmul(out, out, sc_r2);
}
-void curve448_scalar_sub(curve448_scalar_t out, const curve448_scalar_t a,
+void
+ossl_curve448_scalar_sub(curve448_scalar_t out, const curve448_scalar_t a,
const curve448_scalar_t b)
{
sc_subx(out, a->limb, b, sc_p, 0);
}
-void curve448_scalar_add(curve448_scalar_t out, const curve448_scalar_t a,
+void
+ossl_curve448_scalar_add(curve448_scalar_t out, const curve448_scalar_t a,
const curve448_scalar_t b)
{
c448_dword_t chain = 0;
@@ -148,9 +150,9 @@ static ossl_inline void scalar_decode_short(curve448_scalar_t s,
}
}
-c448_error_t curve448_scalar_decode(
- curve448_scalar_t s,
- const unsigned char ser[C448_SCALAR_BYTES])
+c448_error_t
+ossl_curve448_scalar_decode(curve448_scalar_t s,
+ const unsigned char ser[C448_SCALAR_BYTES])
{
unsigned int i;
c448_dsword_t accum = 0;
@@ -160,24 +162,25 @@ c448_error_t curve448_scalar_decode(
accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS;
/* Here accum == 0 or -1 */
- curve448_scalar_mul(s, s, curve448_scalar_one); /* ham-handed reduce */
+ ossl_curve448_scalar_mul(s, s, ossl_curve448_scalar_one); /* ham-handed reduce */
return c448_succeed_if(~word_is_zero((uint32_t)accum));
}
-void curve448_scalar_destroy(curve448_scalar_t scalar)
+void ossl_curve448_scalar_destroy(curve448_scalar_t scalar)
{
OPENSSL_cleanse(scalar, sizeof(curve448_scalar_t));
}
-void curve448_scalar_decode_long(curve448_scalar_t s,
+void
+ossl_curve448_scalar_decode_long(curve448_scalar_t s,
const unsigned char *ser, size_t ser_len)
{
size_t i;
curve448_scalar_t t1, t2;
if (ser_len == 0) {
- curve448_scalar_copy(s, curve448_scalar_zero);
+ curve448_scalar_copy(s, ossl_curve448_scalar_zero);
return;
}
@@ -190,24 +193,25 @@ void curve448_scalar_decode_long(curve448_scalar_t s,
if (ser_len == sizeof(curve448_scalar_t)) {
assert(i == 0);
/* ham-handed reduce */
- curve448_scalar_mul(s, t1, curve448_scalar_one);
- curve448_scalar_destroy(t1);
+ ossl_curve448_scalar_mul(s, t1, ossl_curve448_scalar_one);
+ ossl_curve448_scalar_destroy(t1);
return;
}
while (i) {
i -= C448_SCALAR_BYTES;
sc_montmul(t1, t1, sc_r2);
- (void)curve448_scalar_decode(t2, ser + i);
- curve448_scalar_add(t1, t1, t2);
+ (void)ossl_curve448_scalar_decode(t2, ser + i);
+ ossl_curve448_scalar_add(t1, t1, t2);
}
curve448_scalar_copy(s, t1);
- curve448_scalar_destroy(t1);
- curve448_scalar_destroy(t2);
+ ossl_curve448_scalar_destroy(t1);
+ ossl_curve448_scalar_destroy(t2);
}
-void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
+void
+ossl_curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
const curve448_scalar_t s)
{
unsigned int i, j, k = 0;
@@ -218,7 +222,8 @@ void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
}
}
-void curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a)
+void
+ossl_curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a)
{
c448_word_t mask = 0 - (a->limb[0] & 1);
c448_dword_t chain = 0;
diff --git a/crypto/ec/curve448/word.h b/crypto/ec/curve448/word.h
index 237cc9b63139..f8292eef88f2 100644
--- a/crypto/ec/curve448/word.h
+++ b/crypto/ec/curve448/word.h
@@ -1,8 +1,8 @@
/*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2014 Cryptography Research, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -17,15 +17,20 @@
# include <assert.h>
# include <stdlib.h>
# include <openssl/e_os2.h>
-# include "arch_intrinsics.h"
# include "curve448utils.h"
+# ifdef INT128_MAX
+# include "arch_64/arch_intrinsics.h"
+# else
+# include "arch_32/arch_intrinsics.h"
+# endif
+
# if (ARCH_WORD_BITS == 64)
typedef uint64_t word_t, mask_t;
-typedef __uint128_t dword_t;
+typedef uint128_t dword_t;
typedef int32_t hsword_t;
typedef int64_t sword_t;
-typedef __int128_t dsword_t;
+typedef int128_t dsword_t;
# elif (ARCH_WORD_BITS == 32)
typedef uint32_t word_t, mask_t;
typedef uint64_t dword_t;
diff --git a/crypto/ec/ec2_oct.c b/crypto/ec/ec2_oct.c
index 788e6501fbcd..10a4932591d6 100644
--- a/crypto/ec/ec2_oct.c
+++ b/crypto/ec/ec2_oct.c
@@ -2,12 +2,18 @@
* Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
#include "ec_local.h"
@@ -30,23 +36,22 @@
* the same method, but claim no priority date earlier than July 29, 1994
* (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
*/
-int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
- EC_POINT *point,
- const BIGNUM *x_, int y_bit,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x_, int y_bit,
+ BN_CTX *ctx)
{
- BN_CTX *new_ctx = NULL;
BIGNUM *tmp, *x, *y, *z;
int ret = 0, z0;
-
- /* clear error queue */
- ERR_clear_error();
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
+#endif
y_bit = (y_bit != 0) ? 1 : 0;
@@ -72,19 +77,24 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
goto err;
if (!BN_GF2m_add(tmp, x, tmp))
goto err;
+ ERR_set_mark();
if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
+#ifndef FIPS_MODULE
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_BN
&& ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
- ERR_clear_error();
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
- EC_R_INVALID_COMPRESSED_POINT);
+ ERR_pop_to_mark();
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT);
} else
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
- ERR_R_BN_LIB);
+#endif
+ {
+ ERR_clear_last_mark();
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ }
goto err;
}
+ ERR_clear_last_mark();
z0 = (BN_is_odd(z)) ? 1 : 0;
if (!group->meth->field_mul(group, y, x, z, ctx))
goto err;
@@ -101,7 +111,9 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -110,20 +122,23 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
* length will be returned. If the length len of buf is smaller than required
* an error will be returned.
*/
-size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
- point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
+size_t ossl_ec_GF2m_simple_point2oct(const EC_GROUP *group,
+ const EC_POINT *point,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
{
size_t ret;
- BN_CTX *new_ctx = NULL;
int used_ctx = 0;
BIGNUM *x, *y, *yxi;
size_t field_len, i, skip;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if ((form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM);
goto err;
}
@@ -131,7 +146,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
@@ -148,15 +163,17 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
+#endif
BN_CTX_start(ctx);
used_ctx = 1;
@@ -181,7 +198,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
skip = field_len - BN_num_bytes(x);
if (skip > field_len) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
@@ -191,7 +208,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -199,7 +216,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|| form == POINT_CONVERSION_HYBRID) {
skip = field_len - BN_num_bytes(y);
if (skip > field_len) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
@@ -211,20 +228,24 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
}
if (i != ret) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (used_ctx)
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
err:
if (used_ctx)
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return 0;
}
@@ -232,19 +253,21 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
* Converts an octet string representation to an EC_POINT. Note that the
* simple implementation only uses affine coordinates.
*/
-int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len,
+ BN_CTX *ctx)
{
point_conversion_form_t form;
int y_bit, m;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *yxi;
size_t field_len, enc_len;
int ret = 0;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (len == 0) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -265,18 +288,18 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
/* The point at infinity is represented by a single zero octet. */
if (form == 0) {
if (len != 1) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -290,15 +313,17 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
if (len != enc_len) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
+#endif
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
@@ -310,7 +335,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!BN_bin2bn(buf + 1, field_len, x))
goto err;
if (BN_num_bits(x) > m) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -321,7 +346,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
goto err;
if (BN_num_bits(y) > m) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID) {
@@ -332,14 +357,14 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
*/
if (BN_is_zero(x)) {
if (y_bit != 0) {
- ECerr(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
} else {
if (!group->meth->field_div(group, yxi, y, x, ctx))
goto err;
if (y_bit != BN_is_odd(yxi)) {
- ECerr(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
}
@@ -357,7 +382,9 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
#endif
diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c
index 84e5537a034a..3a59544c8b2f 100644
--- a/crypto/ec/ec2_smpl.c
+++ b/crypto/ec/ec2_smpl.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
#include "crypto/bn.h"
@@ -19,7 +25,7 @@
* Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members
* are handled by EC_GROUP_new.
*/
-int ec_GF2m_simple_group_init(EC_GROUP *group)
+int ossl_ec_GF2m_simple_group_init(EC_GROUP *group)
{
group->field = BN_new();
group->a = BN_new();
@@ -38,7 +44,7 @@ int ec_GF2m_simple_group_init(EC_GROUP *group)
* Free a GF(2^m)-based EC_GROUP structure. Note that all other members are
* handled by EC_GROUP_free.
*/
-void ec_GF2m_simple_group_finish(EC_GROUP *group)
+void ossl_ec_GF2m_simple_group_finish(EC_GROUP *group)
{
BN_free(group->field);
BN_free(group->a);
@@ -49,7 +55,7 @@ void ec_GF2m_simple_group_finish(EC_GROUP *group)
* Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other
* members are handled by EC_GROUP_clear_free.
*/
-void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
+void ossl_ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
{
BN_clear_free(group->field);
BN_clear_free(group->a);
@@ -66,7 +72,7 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
* Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are
* handled by EC_GROUP_copy.
*/
-int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+int ossl_ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
if (!BN_copy(dest->field, src->field))
return 0;
@@ -92,9 +98,9 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
}
/* Set the curve parameters of an EC_GROUP structure. */
-int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
- const BIGNUM *p, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_group_set_curve(EC_GROUP *group,
+ const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0, i;
@@ -103,7 +109,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
goto err;
i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1;
if ((i != 5) && (i != 3)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD);
goto err;
}
@@ -132,8 +138,8 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
* Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL
* then there values will not be set but the method will return with success.
*/
-int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
- BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
+ BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
@@ -162,7 +168,7 @@ int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
* Gets the degree of the field. For a curve over GF(2^m) this is the value
* m.
*/
-int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
+int ossl_ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
{
return BN_num_bits(group->field) - 1;
}
@@ -171,21 +177,22 @@ int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
* Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an
* elliptic curve <=> b != 0 (mod p)
*/
-int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
+ BN_CTX *ctx)
{
int ret = 0;
BIGNUM *b;
+#ifndef FIPS_MODULE
BN_CTX *new_ctx = NULL;
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT,
- ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
+#endif
BN_CTX_start(ctx);
b = BN_CTX_get(ctx);
if (b == NULL)
@@ -205,12 +212,14 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
/* Initializes an EC_POINT. */
-int ec_GF2m_simple_point_init(EC_POINT *point)
+int ossl_ec_GF2m_simple_point_init(EC_POINT *point)
{
point->X = BN_new();
point->Y = BN_new();
@@ -226,7 +235,7 @@ int ec_GF2m_simple_point_init(EC_POINT *point)
}
/* Frees an EC_POINT. */
-void ec_GF2m_simple_point_finish(EC_POINT *point)
+void ossl_ec_GF2m_simple_point_finish(EC_POINT *point)
{
BN_free(point->X);
BN_free(point->Y);
@@ -234,7 +243,7 @@ void ec_GF2m_simple_point_finish(EC_POINT *point)
}
/* Clears and frees an EC_POINT. */
-void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
+void ossl_ec_GF2m_simple_point_clear_finish(EC_POINT *point)
{
BN_clear_free(point->X);
BN_clear_free(point->Y);
@@ -246,7 +255,7 @@ void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
* Copy the contents of one EC_POINT into another. Assumes dest is
* initialized.
*/
-int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+int ossl_ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
{
if (!BN_copy(dest->X, src->X))
return 0;
@@ -264,8 +273,8 @@ int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
* Set an EC_POINT to the point at infinity. A point at infinity is
* represented by having Z=0.
*/
-int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
- EC_POINT *point)
+int ossl_ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
+ EC_POINT *point)
{
point->Z_is_one = 0;
BN_zero(point->Z);
@@ -276,15 +285,15 @@ int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
* Set the coordinates of an EC_POINT using affine coordinates. Note that
* the simple implementation only uses affine coordinates.
*/
-int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
- EC_POINT *point,
- const BIGNUM *x,
- const BIGNUM *y, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x,
+ const BIGNUM *y,
+ BN_CTX *ctx)
{
int ret = 0;
if (x == NULL || y == NULL) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES,
- ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -308,22 +317,20 @@ int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
* Gets the affine coordinates of an EC_POINT. Note that the simple
* implementation only uses affine coordinates.
*/
-int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if (BN_cmp(point->Z, BN_value_one())) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (x != NULL) {
@@ -346,12 +353,14 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
* Computes a + b and stores the result in r. r could be a or b, a could be
* b. Uses algorithm A.10.2 of IEEE P1363.
*/
-int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r,
+ const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
{
- BN_CTX *new_ctx = NULL;
BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
int ret = 0;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (EC_POINT_is_at_infinity(group, a)) {
if (!EC_POINT_copy(r, b))
@@ -365,11 +374,13 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
return 1;
}
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
+#endif
BN_CTX_start(ctx);
x0 = BN_CTX_get(ctx);
@@ -453,7 +464,9 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -461,26 +474,28 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
* Computes 2 * a and stores the result in r. r could be a. Uses algorithm
* A.10.2 of IEEE P1363.
*/
-int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r,
+ const EC_POINT *a, BN_CTX *ctx)
{
- return ec_GF2m_simple_add(group, r, a, a, ctx);
+ return ossl_ec_GF2m_simple_add(group, r, a, a, ctx);
}
-int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point,
+ BN_CTX *ctx)
{
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
/* point is its own inverse */
return 1;
- if (!EC_POINT_make_affine(group, point, ctx))
+ if (group->meth->make_affine == NULL
+ || !group->meth->make_affine(group, point, ctx))
return 0;
return BN_GF2m_add(point->Y, point->X, point->Y);
}
/* Indicates whether the given point is the point at infinity. */
-int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
- const EC_POINT *point)
+int ossl_ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
+ const EC_POINT *point)
{
return BN_is_zero(point->Z);
}
@@ -490,15 +505,17 @@ int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
* in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
* y^2 + x*y = x^3 + a*x^2 + b.
*/
-int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
{
int ret = -1;
- BN_CTX *new_ctx = NULL;
BIGNUM *lh, *y2;
int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
const BIGNUM *, BN_CTX *);
int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (EC_POINT_is_at_infinity(group, point))
return 1;
@@ -510,11 +527,13 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
if (!point->Z_is_one)
return -1;
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return -1;
}
+#endif
BN_CTX_start(ctx);
y2 = BN_CTX_get(ctx);
@@ -546,7 +565,9 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -557,12 +578,14 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
* 0 equal (in affine coordinates)
* 1 not equal
*/
-int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
{
BIGNUM *aX, *aY, *bX, *bY;
- BN_CTX *new_ctx = NULL;
int ret = -1;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (EC_POINT_is_at_infinity(group, a)) {
return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
@@ -575,11 +598,13 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
}
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return -1;
}
+#endif
BN_CTX_start(ctx);
aX = BN_CTX_get(ctx);
@@ -597,26 +622,32 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
/* Forces the given EC_POINT to internally use affine coordinates. */
-int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
- BN_CTX *ctx)
+int ossl_ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
+ BN_CTX *ctx)
{
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
int ret = 0;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
return 1;
+#ifndef FIPS_MODULE
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
+#endif
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
@@ -638,15 +669,17 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
/*
* Forces each of the EC_POINTs in the given array to use affine coordinates.
*/
-int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
- EC_POINT *points[], BN_CTX *ctx)
+int ossl_ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx)
{
size_t i;
@@ -659,22 +692,22 @@ int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
}
/* Wrapper to simple binary polynomial field multiplication implementation. */
-int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r,
- const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
}
/* Wrapper to simple binary polynomial field squaring implementation. */
-int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
- const BIGNUM *a, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
{
return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
}
/* Wrapper to simple binary polynomial field division implementation. */
-int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
- const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
return BN_GF2m_mod_div(r, a, b, group->field, ctx);
}
@@ -696,9 +729,9 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group,
/* s blinding: make sure lambda (s->Z here) is not zero */
do {
- if (!BN_priv_rand(s->Z, BN_num_bits(group->field) - 1,
- BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
+ if (!BN_priv_rand_ex(s->Z, BN_num_bits(group->field) - 1,
+ BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
} while (BN_is_zero(s->Z));
@@ -711,9 +744,9 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group,
/* r blinding: make sure lambda (r->Y here for storage) is not zero */
do {
- if (!BN_priv_rand(r->Y, BN_num_bits(group->field) - 1,
- BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
+ if (!BN_priv_rand_ex(r->Y, BN_num_bits(group->field) - 1,
+ BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
} while (BN_is_zero(r->Y));
@@ -782,7 +815,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
if (BN_is_zero(s->Z)) {
if (!EC_POINT_copy(r, p)
|| !EC_POINT_invert(group, r, ctx)) {
- ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
return 1;
@@ -793,7 +826,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t2 == NULL) {
- ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -856,15 +889,15 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
* order or cofactor set to 0.
*/
if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor))
- return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ return ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
if (scalar != NULL && num == 0)
/* Fixed point multiplication */
- return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
+ return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
if (scalar == NULL && num == 1)
/* Variable point multiplication */
- return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
+ return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
/*-
* Double point multiplication:
@@ -872,12 +905,12 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
*/
if ((t = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (!ec_scalar_mul_ladder(group, t, scalar, NULL, ctx)
- || !ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx)
+ if (!ossl_ec_scalar_mul_ladder(group, t, scalar, NULL, ctx)
+ || !ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx)
|| !EC_POINT_add(group, r, t, r, ctx))
goto err;
@@ -899,7 +932,7 @@ static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
int ret;
if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx)))
- ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
+ ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT);
return ret;
}
@@ -908,54 +941,55 @@ const EC_METHOD *EC_GF2m_simple_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_characteristic_two_field,
- ec_GF2m_simple_group_init,
- ec_GF2m_simple_group_finish,
- ec_GF2m_simple_group_clear_finish,
- ec_GF2m_simple_group_copy,
- ec_GF2m_simple_group_set_curve,
- ec_GF2m_simple_group_get_curve,
- ec_GF2m_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GF2m_simple_group_check_discriminant,
- ec_GF2m_simple_point_init,
- ec_GF2m_simple_point_finish,
- ec_GF2m_simple_point_clear_finish,
- ec_GF2m_simple_point_copy,
- ec_GF2m_simple_point_set_to_infinity,
- 0, /* set_Jprojective_coordinates_GFp */
- 0, /* get_Jprojective_coordinates_GFp */
- ec_GF2m_simple_point_set_affine_coordinates,
- ec_GF2m_simple_point_get_affine_coordinates,
+ ossl_ec_GF2m_simple_group_init,
+ ossl_ec_GF2m_simple_group_finish,
+ ossl_ec_GF2m_simple_group_clear_finish,
+ ossl_ec_GF2m_simple_group_copy,
+ ossl_ec_GF2m_simple_group_set_curve,
+ ossl_ec_GF2m_simple_group_get_curve,
+ ossl_ec_GF2m_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GF2m_simple_group_check_discriminant,
+ ossl_ec_GF2m_simple_point_init,
+ ossl_ec_GF2m_simple_point_finish,
+ ossl_ec_GF2m_simple_point_clear_finish,
+ ossl_ec_GF2m_simple_point_copy,
+ ossl_ec_GF2m_simple_point_set_to_infinity,
+ ossl_ec_GF2m_simple_point_set_affine_coordinates,
+ ossl_ec_GF2m_simple_point_get_affine_coordinates,
0, /* point_set_compressed_coordinates */
0, /* point2oct */
0, /* oct2point */
- ec_GF2m_simple_add,
- ec_GF2m_simple_dbl,
- ec_GF2m_simple_invert,
- ec_GF2m_simple_is_at_infinity,
- ec_GF2m_simple_is_on_curve,
- ec_GF2m_simple_cmp,
- ec_GF2m_simple_make_affine,
- ec_GF2m_simple_points_make_affine,
+ ossl_ec_GF2m_simple_add,
+ ossl_ec_GF2m_simple_dbl,
+ ossl_ec_GF2m_simple_invert,
+ ossl_ec_GF2m_simple_is_at_infinity,
+ ossl_ec_GF2m_simple_is_on_curve,
+ ossl_ec_GF2m_simple_cmp,
+ ossl_ec_GF2m_simple_make_affine,
+ ossl_ec_GF2m_simple_points_make_affine,
ec_GF2m_simple_points_mul,
0, /* precompute_mult */
0, /* have_precompute_mult */
- ec_GF2m_simple_field_mul,
- ec_GF2m_simple_field_sqr,
- ec_GF2m_simple_field_div,
+ ossl_ec_GF2m_simple_field_mul,
+ ossl_ec_GF2m_simple_field_sqr,
+ ossl_ec_GF2m_simple_field_div,
ec_GF2m_simple_field_inv,
0, /* field_encode */
0, /* field_decode */
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
ec_GF2m_simple_ladder_pre,
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 5098bd7a6602..d4348ff244c7 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -1,34 +1,38 @@
/*
- * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDH and ECDSA 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>
#include <openssl/ec.h>
#include <openssl/bn.h>
-#include <openssl/cms.h>
#include <openssl/asn1t.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "crypto/x509.h"
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "ec_local.h"
-#ifndef OPENSSL_NO_CMS
-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, const EC_KEY *ec_key)
{
const EC_GROUP *group;
int nid;
+
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
- ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return 0;
}
if (EC_GROUP_get_asn1_flag(group)
@@ -38,8 +42,7 @@ static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid);
if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
- ASN1_OBJECT_free(asn1obj);
- ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_OID);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID);
return 0;
}
*ppval = asn1obj;
@@ -50,20 +53,10 @@ static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
pstr = ASN1_STRING_new();
if (pstr == NULL)
return 0;
-
- /*
- * The cast in the following line is intentional as the
- * `i2d_ECParameters` signature can't be constified (see discussion at
- * https://github.com/openssl/openssl/pull/9347 where related and
- * required constification backports were rejected).
- *
- * This cast should be safe anyway, because we can expect
- * `i2d_ECParameters()` to treat the first argument as if it was const.
- */
- pstr->length = i2d_ECParameters((EC_KEY *)ec_key, &pstr->data);
+ pstr->length = i2d_ECParameters(ec_key, &pstr->data);
if (pstr->length <= 0) {
ASN1_STRING_free(pstr);
- ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
*ppval = pstr;
@@ -81,7 +74,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
int penclen;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
penclen = i2o_ECPublicKey(ec_key, NULL);
@@ -98,80 +91,32 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
ptype, pval, penc, penclen))
return 1;
err:
- if (ptype == V_ASN1_OBJECT)
- ASN1_OBJECT_free(pval);
- else
+ if (ptype == V_ASN1_SEQUENCE)
ASN1_STRING_free(pval);
OPENSSL_free(penc);
return 0;
}
-static EC_KEY *eckey_type2param(int ptype, const void *pval)
-{
- EC_KEY *eckey = NULL;
- EC_GROUP *group = NULL;
-
- if (ptype == V_ASN1_SEQUENCE) {
- const ASN1_STRING *pstr = pval;
- const unsigned char *pm = pstr->data;
- int pmlen = pstr->length;
-
- if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
- ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
- goto ecerr;
- }
- } else if (ptype == V_ASN1_OBJECT) {
- const ASN1_OBJECT *poid = pval;
-
- /*
- * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
- */
- if ((eckey = EC_KEY_new()) == NULL) {
- ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
- goto ecerr;
- }
- group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
- if (group == NULL)
- goto ecerr;
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
- if (EC_KEY_set_group(eckey, group) == 0)
- goto ecerr;
- EC_GROUP_free(group);
- } else {
- ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
- goto ecerr;
- }
-
- return eckey;
-
- ecerr:
- EC_KEY_free(eckey);
- EC_GROUP_free(group);
- return NULL;
-}
-
-static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
{
const unsigned char *p = NULL;
- const void *pval;
- int ptype, pklen;
+ int pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;
+ OSSL_LIB_CTX *libctx = NULL;
+ const char *propq = NULL;
- if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+ if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)
+ || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval);
+ eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq);
- if (!eckey) {
- ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+ if (!eckey)
return 0;
- }
/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
- ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
goto ecerr;
}
@@ -189,6 +134,7 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
*pb = EC_KEY_get0_public_key(b->pkey.ec);
+
if (group == NULL || pa == NULL || pb == NULL)
return -2;
r = EC_POINT_cmp(group, pa, pb, NULL);
@@ -199,49 +145,30 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return -2;
}
-static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
+ OSSL_LIB_CTX *libctx, const char *propq)
{
- const unsigned char *p = NULL;
- const void *pval;
- int ptype, pklen;
- EC_KEY *eckey = NULL;
- const X509_ALGOR *palg;
-
- if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
- return 0;
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval);
-
- if (!eckey)
- goto ecliberr;
+ int ret = 0;
+ EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq);
- /* We have parameters now set private key */
- if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
- ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
- goto ecerr;
+ if (eckey != NULL) {
+ ret = 1;
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
}
- EVP_PKEY_assign_EC_KEY(pkey, eckey);
- return 1;
-
- ecliberr:
- ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
- ecerr:
- EC_KEY_free(eckey);
- return 0;
+ return ret;
}
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
EC_KEY ec_key = *(pkey->pkey.ec);
- unsigned char *ep, *p;
+ unsigned char *ep = NULL;
int eplen, ptype;
void *pval;
unsigned int old_flags;
if (!eckey_param2type(&ptype, &pval, &ec_key)) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
return 0;
}
@@ -254,30 +181,25 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
old_flags = EC_KEY_get_enc_flags(&ec_key);
EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
- eplen = i2d_ECPrivateKey(&ec_key, NULL);
- if (!eplen) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
- return 0;
- }
- ep = OPENSSL_malloc(eplen);
- if (ep == NULL) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- p = ep;
- if (!i2d_ECPrivateKey(&ec_key, &p)) {
- OPENSSL_free(ep);
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
- return 0;
+ eplen = i2d_ECPrivateKey(&ec_key, &ep);
+ if (eplen <= 0) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+ goto err;
}
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
ptype, pval, ep, eplen)) {
- OPENSSL_free(ep);
- return 0;
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
+ OPENSSL_clear_free(ep, eplen);
+ goto err;
}
return 1;
+
+ err:
+ if (ptype == V_ASN1_SEQUENCE)
+ ASN1_STRING_free(pval);
+ return 0;
}
static int int_ec_size(const EVP_PKEY *pkey)
@@ -293,6 +215,7 @@ static int ec_bits(const EVP_PKEY *pkey)
static int ec_security_bits(const EVP_PKEY *pkey)
{
int ecbits = ec_bits(pkey);
+
if (ecbits >= 512)
return 256;
if (ecbits >= 384)
@@ -337,6 +260,7 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
*group_b = EC_KEY_get0_group(b->pkey.ec);
+
if (group_a == NULL || group_b == NULL)
return -2;
if (EC_GROUP_cmp(group_a, group_b, NULL))
@@ -365,7 +289,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
const EC_GROUP *group;
if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
- ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -413,7 +337,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
ret = 1;
err:
if (!ret)
- ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
OPENSSL_clear_free(priv, privlen);
OPENSSL_free(pub);
return ret;
@@ -424,10 +348,8 @@ static int eckey_param_decode(EVP_PKEY *pkey,
{
EC_KEY *eckey;
- if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) {
- ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+ if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL)
return 0;
- }
EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;
}
@@ -460,10 +382,8 @@ static int old_ec_priv_decode(EVP_PKEY *pkey,
{
EC_KEY *ec;
- if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) {
- ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+ if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL)
return 0;
- }
EVP_PKEY_assign_EC_KEY(pkey, ec);
return 1;
}
@@ -476,61 +396,20 @@ static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op) {
- case ASN1_PKEY_CTRL_PKCS7_SIGN:
- if (arg1 == 0) {
- int snid, hnid;
- X509_ALGOR *alg1, *alg2;
- PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
- if (alg1 == NULL || alg1->algorithm == NULL)
- return -1;
- hnid = OBJ_obj2nid(alg1->algorithm);
- if (hnid == NID_undef)
- return -1;
- if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
- return -1;
- X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
- }
- return 1;
-#ifndef OPENSSL_NO_CMS
- case ASN1_PKEY_CTRL_CMS_SIGN:
- if (arg1 == 0) {
- int snid, hnid;
- X509_ALGOR *alg1, *alg2;
- CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
- if (alg1 == NULL || alg1->algorithm == NULL)
- return -1;
- hnid = OBJ_obj2nid(alg1->algorithm);
- if (hnid == NID_undef)
- return -1;
- if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
- return -1;
- X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
- }
- return 1;
-
- case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (arg1 == 1)
- return ecdh_cms_decrypt(arg2);
- else if (arg1 == 0)
- return ecdh_cms_encrypt(arg2);
- return -2;
-
- case ASN1_PKEY_CTRL_CMS_RI_TYPE:
- *(int *)arg2 = CMS_RECIPINFO_AGREE;
- return 1;
-#endif
-
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
- if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
+ if (EVP_PKEY_get_id(pkey) == EVP_PKEY_SM2) {
/* For SM2, the only valid digest-alg is SM3 */
*(int *)arg2 = NID_sm3;
- } else {
- *(int *)arg2 = NID_sha256;
+ return 2; /* Make it mandatory */
}
+ *(int *)arg2 = NID_sha256;
return 1;
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
- return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
+ /* We should only be here if we have a legacy key */
+ if (!ossl_assert(evp_pkey_is_legacy(pkey)))
+ return 0;
+ return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL);
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
@@ -538,9 +417,7 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
default:
return -2;
-
}
-
}
static int ec_pkey_check(const EVP_PKEY *pkey)
@@ -549,7 +426,7 @@ static int ec_pkey_check(const EVP_PKEY *pkey)
/* stay consistent to what EVP_PKEY_check demands */
if (eckey->priv_key == NULL) {
- ECerr(EC_F_EC_PKEY_CHECK, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
return 0;
}
@@ -578,14 +455,200 @@ static int ec_pkey_param_check(const EVP_PKEY *pkey)
/* stay consistent to what EVP_PKEY_check demands */
if (eckey->group == NULL) {
- ECerr(EC_F_EC_PKEY_PARAM_CHECK, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return 0;
}
return EC_GROUP_check(eckey->group, NULL);
}
-const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+static
+size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey)
+{
+ return pkey->pkey.ec->dirty_cnt;
+}
+
+static
+int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
+ OSSL_FUNC_keymgmt_import_fn *importer,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ const EC_KEY *eckey = NULL;
+ const EC_GROUP *ecg = NULL;
+ unsigned char *pub_key_buf = NULL, *gen_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 selection = 0;
+ int rv = 0;
+ BN_CTX *bnctx = NULL;
+
+ if (from == NULL
+ || (eckey = from->pkey.ec) == NULL
+ || (ecg = EC_KEY_get0_group(eckey)) == NULL)
+ return 0;
+
+ tmpl = OSSL_PARAM_BLD_new();
+ if (tmpl == NULL)
+ return 0;
+
+ /*
+ * EC_POINT_point2buf() can generate random numbers in some
+ * implementations so we need to ensure we use the correct libctx.
+ */
+ bnctx = BN_CTX_new_ex(libctx);
+ if (bnctx == NULL)
+ goto err;
+ BN_CTX_start(bnctx);
+
+ /* export the domain parameters */
+ if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
+ goto err;
+ selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
+
+ priv_key = EC_KEY_get0_private_key(eckey);
+ pub_point = EC_KEY_get0_public_key(eckey);
+
+ if (pub_point != NULL) {
+ /* convert pub_point to a octet string according to the SECG standard */
+ point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
+
+ if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
+ format,
+ &pub_key_buf, bnctx)) == 0
+ || !OSSL_PARAM_BLD_push_octet_string(tmpl,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ pub_key_buf,
+ pub_key_buflen))
+ goto err;
+ selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
+ }
+
+ 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;
+ selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
+
+ /*
+ * 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;
+ selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
+ }
+
+ params = OSSL_PARAM_BLD_to_param(tmpl);
+
+ /* We export, the provider imports */
+ rv = importer(to_keydata, selection, params);
+
+ err:
+ OSSL_PARAM_BLD_free(tmpl);
+ OSSL_PARAM_free(params);
+ OPENSSL_free(pub_key_buf);
+ OPENSSL_free(gen_buf);
+ BN_CTX_end(bnctx);
+ BN_CTX_free(bnctx);
+ return rv;
+}
+
+static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
+{
+ EVP_PKEY_CTX *pctx = vpctx;
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery);
+
+ if (ec == NULL) {
+ ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (!ossl_ec_group_fromdata(ec, params)
+ || !ossl_ec_key_otherparams_fromdata(ec, params)
+ || !ossl_ec_key_fromdata(ec, params, 1)
+ || !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
+ EC_KEY_free(ec);
+ return 0;
+ }
+ return 1;
+}
+
+static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
+{
+ EC_KEY *eckey = from->pkey.ec;
+ EC_KEY *dupkey = NULL;
+ int ret;
+
+ if (eckey != NULL) {
+ dupkey = EC_KEY_dup(eckey);
+ if (dupkey == NULL)
+ return 0;
+ } else {
+ /* necessary to properly copy empty SM2 keys */
+ return EVP_PKEY_set_type(to, from->type);
+ }
+
+ ret = EVP_PKEY_assign_EC_KEY(to, dupkey);
+ if (!ret)
+ EC_KEY_free(dupkey);
+ return ret;
+}
+
+const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = {
EVP_PKEY_EC,
EVP_PKEY_EC,
0,
@@ -597,7 +660,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
eckey_pub_cmp,
eckey_pub_print,
- eckey_priv_decode,
+ NULL,
eckey_priv_encode,
eckey_priv_print,
@@ -622,11 +685,22 @@ 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,
+ ec_pkey_import_from,
+ ec_pkey_copy,
+ eckey_priv_decode_ex
};
#if !defined(OPENSSL_NO_SM2)
-const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
+const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = {
EVP_PKEY_SM2,
EVP_PKEY_EC,
ASN1_PKEY_ALIAS
@@ -645,320 +719,3 @@ int ECParameters_print(BIO *bp, const EC_KEY *x)
{
return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
}
-
-#ifndef OPENSSL_NO_CMS
-
-static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
- X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
-{
- const ASN1_OBJECT *aoid;
- int atype;
- const void *aval;
- int rv = 0;
- EVP_PKEY *pkpeer = NULL;
- EC_KEY *ecpeer = NULL;
- const unsigned char *p;
- int plen;
- X509_ALGOR_get0(&aoid, &atype, &aval, alg);
- if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
- goto err;
- /* If absent parameters get group from main key */
- if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
- const EC_GROUP *grp;
- EVP_PKEY *pk;
- pk = EVP_PKEY_CTX_get0_pkey(pctx);
- if (!pk)
- goto err;
- grp = EC_KEY_get0_group(pk->pkey.ec);
- ecpeer = EC_KEY_new();
- if (ecpeer == NULL)
- goto err;
- if (!EC_KEY_set_group(ecpeer, grp))
- goto err;
- } else {
- ecpeer = eckey_type2param(atype, aval);
- if (!ecpeer)
- goto err;
- }
- /* We have parameters now set public key */
- plen = ASN1_STRING_length(pubkey);
- p = ASN1_STRING_get0_data(pubkey);
- if (!p || !plen)
- goto err;
- if (!o2i_ECPublicKey(&ecpeer, &p, plen))
- goto err;
- pkpeer = EVP_PKEY_new();
- if (pkpeer == NULL)
- goto err;
- EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
- if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
- rv = 1;
- err:
- EC_KEY_free(ecpeer);
- EVP_PKEY_free(pkpeer);
- return rv;
-}
-
-/* Set KDF parameters based on KDF NID */
-static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
-{
- int kdf_nid, kdfmd_nid, cofactor;
- const EVP_MD *kdf_md;
- if (eckdf_nid == NID_undef)
- return 0;
-
- /* Lookup KDF type, cofactor mode and digest */
- if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
- return 0;
-
- if (kdf_nid == NID_dh_std_kdf)
- cofactor = 0;
- else if (kdf_nid == NID_dh_cofactor_kdf)
- cofactor = 1;
- else
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
- return 0;
-
- kdf_md = EVP_get_digestbynid(kdfmd_nid);
- if (!kdf_md)
- return 0;
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
- return 0;
- return 1;
-}
-
-static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
-{
- int rv = 0;
-
- X509_ALGOR *alg, *kekalg = NULL;
- ASN1_OCTET_STRING *ukm;
- const unsigned char *p;
- unsigned char *der = NULL;
- int plen, keylen;
- const EVP_CIPHER *kekcipher;
- EVP_CIPHER_CTX *kekctx;
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
- return 0;
-
- if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
- ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
- return 0;
- }
-
- if (alg->parameter->type != V_ASN1_SEQUENCE)
- return 0;
-
- p = alg->parameter->value.sequence->data;
- plen = alg->parameter->value.sequence->length;
- kekalg = d2i_X509_ALGOR(NULL, &p, plen);
- if (!kekalg)
- goto err;
- kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- if (!kekctx)
- goto err;
- kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
- if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
- goto err;
- if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
- goto err;
- if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
- goto err;
-
- keylen = EVP_CIPHER_CTX_key_length(kekctx);
- if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
-
- plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
-
- if (!plen)
- goto err;
-
- if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
- goto err;
- der = NULL;
-
- rv = 1;
- err:
- X509_ALGOR_free(kekalg);
- OPENSSL_free(der);
- return rv;
-}
-
-static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (!pctx)
- return 0;
- /* See if we need to set peer key */
- if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
- X509_ALGOR *alg;
- ASN1_BIT_STRING *pubkey;
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
- NULL, NULL, NULL))
- return 0;
- if (!alg || !pubkey)
- return 0;
- if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
- ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
- return 0;
- }
- }
- /* Set ECDH derivation parameters and initialise unwrap context */
- if (!ecdh_cms_set_shared_info(pctx, ri)) {
- ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
- return 0;
- }
- return 1;
-}
-
-static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
-{
- EVP_PKEY_CTX *pctx;
- EVP_PKEY *pkey;
- EVP_CIPHER_CTX *ctx;
- int keylen;
- X509_ALGOR *talg, *wrap_alg = NULL;
- const ASN1_OBJECT *aoid;
- ASN1_BIT_STRING *pubkey;
- ASN1_STRING *wrap_str;
- ASN1_OCTET_STRING *ukm;
- unsigned char *penc = NULL;
- int penclen;
- int rv = 0;
- int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
- const EVP_MD *kdf_md;
- pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
- if (!pctx)
- return 0;
- /* Get ephemeral key */
- pkey = EVP_PKEY_CTX_get0_pkey(pctx);
- if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
- NULL, NULL, NULL))
- goto err;
- X509_ALGOR_get0(&aoid, NULL, NULL, talg);
- /* Is everything uninitialised? */
- if (aoid == OBJ_nid2obj(NID_undef)) {
-
- EC_KEY *eckey = pkey->pkey.ec;
- /* Set the key */
- unsigned char *p;
-
- penclen = i2o_ECPublicKey(eckey, NULL);
- if (penclen <= 0)
- goto err;
- penc = OPENSSL_malloc(penclen);
- if (penc == NULL)
- goto err;
- p = penc;
- penclen = i2o_ECPublicKey(eckey, &p);
- if (penclen <= 0)
- goto err;
- ASN1_STRING_set0(pubkey, penc, penclen);
- pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
- pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
- V_ASN1_UNDEF, NULL);
- }
-
- /* See if custom parameters set */
- kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
- if (kdf_type <= 0)
- goto err;
- if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
- goto err;
- ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
- if (ecdh_nid < 0)
- goto err;
- else if (ecdh_nid == 0)
- ecdh_nid = NID_dh_std_kdf;
- else if (ecdh_nid == 1)
- ecdh_nid = NID_dh_cofactor_kdf;
-
- if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
- kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
- if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
- goto err;
- } else
- /* Unknown KDF */
- goto err;
- if (kdf_md == NULL) {
- /* Fixme later for better MD */
- kdf_md = EVP_sha1();
- if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
- goto err;
- }
-
- if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
- goto err;
-
- /* Lookup NID for KDF+cofactor+digest */
-
- if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
- goto err;
- /* Get wrap NID */
- ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
- wrap_nid = EVP_CIPHER_CTX_type(ctx);
- keylen = EVP_CIPHER_CTX_key_length(ctx);
-
- /* Package wrap algorithm in an AlgorithmIdentifier */
-
- wrap_alg = X509_ALGOR_new();
- if (wrap_alg == NULL)
- goto err;
- wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
- wrap_alg->parameter = ASN1_TYPE_new();
- if (wrap_alg->parameter == NULL)
- goto err;
- if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
- goto err;
- if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
- ASN1_TYPE_free(wrap_alg->parameter);
- wrap_alg->parameter = NULL;
- }
-
- if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
- goto err;
-
- penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
-
- if (!penclen)
- goto err;
-
- if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
- goto err;
- penc = NULL;
-
- /*
- * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
- * of another AlgorithmIdentifier.
- */
- penclen = i2d_X509_ALGOR(wrap_alg, &penc);
- if (!penc || !penclen)
- goto err;
- wrap_str = ASN1_STRING_new();
- if (wrap_str == NULL)
- goto err;
- ASN1_STRING_set0(wrap_str, penc, penclen);
- penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
-
- rv = 1;
-
- err:
- OPENSSL_free(penc);
- X509_ALGOR_free(wrap_alg);
- return rv;
-}
-
-#endif
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 1acbbde3d37b..c018f392894d 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -1,90 +1,27 @@
/*
* Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include "ec_local.h"
#include <openssl/err.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include "internal/nelem.h"
+#include "crypto/asn1_dsa.h"
-int EC_GROUP_get_basis_type(const EC_GROUP *group)
-{
- int i;
-
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
- NID_X9_62_characteristic_two_field)
- /* everything else is currently not supported */
- return 0;
-
- /* Find the last non-zero element of group->poly[] */
- for (i = 0;
- i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
- i++)
- continue;
-
- if (i == 4)
- return NID_X9_62_ppBasis;
- else if (i == 2)
- return NID_X9_62_tpBasis;
- else
- /* everything else is currently not supported */
- return 0;
-}
-
-#ifndef OPENSSL_NO_EC2M
-int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
-{
- if (group == NULL)
- return 0;
-
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
- NID_X9_62_characteristic_two_field
- || !((group->poly[0] != 0) && (group->poly[1] != 0)
- && (group->poly[2] == 0))) {
- ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-
- if (k)
- *k = group->poly[1];
-
- return 1;
-}
-
-int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
- unsigned int *k2, unsigned int *k3)
-{
- if (group == NULL)
- return 0;
-
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
- NID_X9_62_characteristic_two_field
- || !((group->poly[0] != 0) && (group->poly[1] != 0)
- && (group->poly[2] != 0) && (group->poly[3] != 0)
- && (group->poly[4] == 0))) {
- ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-
- if (k1)
- *k1 = group->poly[3];
- if (k2)
- *k2 = group->poly[2];
- if (k3)
- *k3 = group->poly[1];
-
- return 1;
-}
-#endif
+#ifndef FIPS_MODULE
/* some structures needed for the asn1 encoding */
typedef struct x9_62_pentanomial_st {
@@ -223,9 +160,9 @@ ASN1_CHOICE(ECPKPARAMETERS) = {
ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
} ASN1_CHOICE_END(ECPKPARAMETERS)
-DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
-IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_FUNCTIONS(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECPKPARAMETERS, ECPKPARAMETERS)
+IMPLEMENT_ASN1_FUNCTIONS(ECPKPARAMETERS)
ASN1_SEQUENCE(EC_PRIVATEKEY) = {
ASN1_EMBED(EC_PRIVATEKEY, version, INT32),
@@ -234,9 +171,9 @@ ASN1_SEQUENCE(EC_PRIVATEKEY) = {
ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
} static_ASN1_SEQUENCE_END(EC_PRIVATEKEY)
-DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
-IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_FUNCTIONS(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(EC_PRIVATEKEY, EC_PRIVATEKEY)
+IMPLEMENT_ASN1_FUNCTIONS(EC_PRIVATEKEY)
/* some declarations of internal function */
@@ -259,33 +196,33 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
ASN1_OBJECT_free(field->fieldType);
ASN1_TYPE_free(field->p.other);
- nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+ nid = EC_GROUP_get_field_type(group);
/* set OID for the field */
if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB);
goto err;
}
if (nid == NID_X9_62_prime_field) {
if ((tmp = BN_new()) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
/* the parameters are specified by the prime number p */
if (!EC_GROUP_get_curve(group, tmp, NULL, NULL, NULL)) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* set the prime number */
field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
if (field->p.prime == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
} else if (nid == NID_X9_62_characteristic_two_field)
#ifdef OPENSSL_NO_EC2M
{
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
goto err;
}
#else
@@ -297,7 +234,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
char_two = field->p.char_two;
if (char_two == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -306,12 +243,12 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
field_type = EC_GROUP_get_basis_type(group);
if (field_type == 0) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* set base type OID */
if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB);
goto err;
}
@@ -323,11 +260,11 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
char_two->p.tpBasis = ASN1_INTEGER_new();
if (char_two->p.tpBasis == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
} else if (field_type == NID_X9_62_ppBasis) {
@@ -338,7 +275,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
if (char_two->p.ppBasis == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -351,14 +288,14 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
/* for ONB the parameters are (asn1) NULL */
char_two->p.onBasis = ASN1_NULL_new();
if (char_two->p.onBasis == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
}
#endif
else {
- ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_UNSUPPORTED_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD);
goto err;
}
@@ -380,13 +317,13 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
return 0;
if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
/* get a and b */
if (!EC_GROUP_get_curve(group, NULL, tmp_1, tmp_2, NULL)) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -398,19 +335,19 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
len = ((size_t)EC_GROUP_get_degree(group) + 7) / 8;
if ((a_buf = OPENSSL_malloc(len)) == NULL
|| (b_buf = OPENSSL_malloc(len)) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (BN_bn2binpad(tmp_1, a_buf, len) < 0
|| BN_bn2binpad(tmp_2, b_buf, len) < 0) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* set a and b */
if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len)
|| !ASN1_OCTET_STRING_set(curve->b, b_buf, len)) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
@@ -418,14 +355,14 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
if (group->seed) {
if (!curve->seed)
if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
(int)group->seed_len)) {
- ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
} else {
@@ -444,7 +381,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
}
ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
- ECPARAMETERS *params)
+ ECPARAMETERS *params)
{
size_t len = 0;
ECPARAMETERS *ret = NULL;
@@ -456,7 +393,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
if (params == NULL) {
if ((ret = ECPARAMETERS_new()) == NULL) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
} else
@@ -467,19 +404,19 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
/* set the fieldID */
if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* set the curve */
if (!ec_asn1_group2curve(group, ret->curve)) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* set the base point */
if ((point = EC_GROUP_get0_generator(group)) == NULL) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
@@ -487,12 +424,12 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
len = EC_POINT_point2buf(group, point, form, &buffer, NULL);
if (len == 0) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
OPENSSL_free(buffer);
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
ASN1_STRING_set0(ret->base, buffer, len);
@@ -500,13 +437,13 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
/* set the order */
tmp = EC_GROUP_get0_order(group);
if (tmp == NULL) {
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
ret->order = BN_to_ASN1_INTEGER(tmp, orig = ret->order);
if (ret->order == NULL) {
ret->order = orig;
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
@@ -516,7 +453,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
ret->cofactor = BN_to_ASN1_INTEGER(tmp, orig = ret->cofactor);
if (ret->cofactor == NULL) {
ret->cofactor = orig;
- ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
}
@@ -537,7 +474,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
if (ret == NULL) {
if ((ret = ECPKPARAMETERS_new()) == NULL) {
- ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else {
@@ -558,7 +495,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
ASN1_OBJECT_free(asn1obj);
- ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID);
ok = 0;
} else {
ret->type = ECPKPARAMETERS_TYPE_NAMED;
@@ -592,9 +529,10 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
int curve_name = NID_undef;
BN_CTX *ctx = NULL;
- if (!params->fieldID || !params->fieldID->fieldType ||
- !params->fieldID->p.ptr) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ if (params->fieldID == NULL
+ || params->fieldID->fieldType == NULL
+ || params->fieldID->p.ptr == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
@@ -604,20 +542,20 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
* encoded them incorrectly, so we must accept any length for backwards
* compatibility.
*/
- if (!params->curve || !params->curve->a ||
- !params->curve->a->data || !params->curve->b ||
- !params->curve->b->data) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ if (params->curve == NULL
+ || params->curve->a == NULL || params->curve->a->data == NULL
+ || params->curve->b == NULL || params->curve->b->data == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
if (a == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
if (b == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -626,7 +564,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
if (tmp == NID_X9_62_characteristic_two_field)
#ifdef OPENSSL_NO_EC2M
{
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_GF2M_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
goto err;
}
#else
@@ -637,12 +575,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
field_bits = char_two->m;
if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
+ ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE);
goto err;
}
if ((p = BN_new()) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -653,15 +591,14 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
long tmp_long;
if (!char_two->p.tpBasis) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
if (!(char_two->m > tmp_long && tmp_long > 0)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
- EC_R_INVALID_TRINOMIAL_BASIS);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS);
goto err;
}
@@ -676,16 +613,15 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
X9_62_PENTANOMIAL *penta;
penta = char_two->p.ppBasis;
- if (!penta) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ if (penta == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
if (!
(char_two->m > penta->k3 && penta->k3 > penta->k2
&& penta->k2 > penta->k1 && penta->k1 > 0)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
- EC_R_INVALID_PENTANOMIAL_BASIS);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS);
goto err;
}
@@ -701,11 +637,11 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
if (!BN_set_bit(p, 0))
goto err;
} else if (tmp == NID_X9_62_onBasis) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_NOT_IMPLEMENTED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_IMPLEMENTED);
goto err;
} else { /* error */
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
@@ -716,36 +652,36 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
else if (tmp == NID_X9_62_prime_field) {
/* we have a curve over a prime field */
/* extract the prime number */
- if (!params->fieldID->p.prime) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ if (params->fieldID->p.prime == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
if (p == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
if (BN_is_negative(p) || BN_is_zero(p)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
goto err;
}
field_bits = BN_num_bits(p);
if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
+ ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE);
goto err;
}
/* create the EC_GROUP structure */
ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
} else {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
goto err;
}
if (ret == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -758,12 +694,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
* zero length allocation request.
*/
if (params->curve->seed->length == 0) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
OPENSSL_free(ret->seed);
if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(ret->seed, params->curve->seed->data,
@@ -775,7 +711,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|| params->base == NULL
|| params->base->data == NULL
|| params->base->length == 0) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
goto err;
}
@@ -789,21 +725,21 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
/* extract the ec point */
if (!EC_POINT_oct2point(ret, point, params->base->data,
params->base->length, NULL)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* extract the order */
if (ASN1_INTEGER_to_BN(params->order, a) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
if (BN_is_negative(a) || BN_is_zero(a)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
@@ -812,12 +748,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
BN_free(b);
b = NULL;
} else if (ASN1_INTEGER_to_BN(params->cofactor, b) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
goto err;
}
/* set the generator, order and cofactor (if present) */
if (!EC_GROUP_set_generator(ret, point, a, b)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -834,16 +770,16 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
* mathematically wrong anyway and should not be used.
*/
if ((ctx = BN_CTX_new()) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if ((dup = EC_GROUP_dup(ret)) == NULL
|| EC_GROUP_set_seed(dup, NULL, 0) != 1
|| !EC_GROUP_set_generator(dup, point, a, NULL)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
- if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
+ if ((curve_name = ossl_ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
/*
* The input explicit parameters successfully matched one of the
* built-in curves: often for built-in curves we have specialized
@@ -865,7 +801,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
EC_GROUP_free(ret);
@@ -917,7 +853,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
int tmp = 0;
if (params == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return NULL;
}
@@ -925,8 +861,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
/* the curve is given by an OID */
tmp = OBJ_obj2nid(params->value.named_curve);
if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS,
- EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
return NULL;
}
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
@@ -934,7 +869,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
/* the parameters are given by an ECPARAMETERS structure */
ret = EC_GROUP_new_from_ecparameters(params->value.parameters);
if (!ret) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return NULL;
}
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
@@ -942,7 +877,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
/* implicit parameters inherited from CA - unsupported */
return NULL;
} else {
- ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR);
return NULL;
}
@@ -958,13 +893,11 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
const unsigned char *p = *in;
if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
- ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) {
- ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
@@ -987,11 +920,11 @@ int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
int ret = 0;
ECPKPARAMETERS *tmp = EC_GROUP_get_ecpkparameters(a, NULL);
if (tmp == NULL) {
- ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE);
return 0;
}
if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
- ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(tmp);
return 0;
}
@@ -1007,14 +940,12 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
EC_PRIVATEKEY *priv_key = NULL;
const unsigned char *p = *in;
- if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL)
return NULL;
- }
if (a == NULL || *a == NULL) {
if ((ret = EC_KEY_new()) == NULL) {
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
} else
@@ -1029,7 +960,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
}
if (ret->group == NULL) {
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -1041,14 +972,17 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
ASN1_STRING_length(pkey)) == 0)
goto err;
} else {
- ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
goto err;
}
+ if (EC_GROUP_get_curve_name(ret->group) == NID_sm2)
+ EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE);
+
EC_POINT_clear_free(ret->pub_key);
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -1059,7 +993,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
pub_oct = ASN1_STRING_get0_data(priv_key->publicKey);
pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) {
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
} else {
@@ -1074,6 +1008,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:
@@ -1083,7 +1018,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
return NULL;
}
-int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out)
{
int ret = 0, ok = 0;
unsigned char *priv= NULL, *pub= NULL;
@@ -1093,12 +1028,12 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
if (a == NULL || a->group == NULL ||
(!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1107,7 +1042,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
privlen = EC_KEY_priv2buf(a, &priv);
if (privlen == 0) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -1118,7 +1053,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
if ((priv_key->parameters =
EC_GROUP_get_ecpkparameters(a->group,
priv_key->parameters)) == NULL) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -1126,14 +1061,14 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
priv_key->publicKey = ASN1_BIT_STRING_new();
if (priv_key->publicKey == NULL) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL);
if (publen == 0) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
@@ -1144,7 +1079,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
}
if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
- ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
ok = 1;
@@ -1155,10 +1090,10 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
return (ok ? ret : 0);
}
-int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+int i2d_ECParameters(const EC_KEY *a, unsigned char **out)
{
if (a == NULL) {
- ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return i2d_ECPKParameters(a->group, out);
@@ -1169,25 +1104,31 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
EC_KEY *ret;
if (in == NULL || *in == NULL) {
- ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (a == NULL || *a == NULL) {
if ((ret = EC_KEY_new()) == NULL) {
- ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else
ret = *a;
if (!d2i_ECPKParameters(&ret->group, in, 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;
}
+ if (EC_GROUP_get_curve_name(ret->group) == NID_sm2)
+ EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE);
+
+ ret->dirty_cnt++;
+
if (a)
*a = ret;
@@ -1202,12 +1143,13 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
/*
* sorry, but a EC_GROUP-structure is necessary to set the public key
*/
- ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
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);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
*in += len;
@@ -1219,8 +1161,8 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
size_t buf_len = 0;
int new_buffer = 0;
- if (a == NULL) {
- ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+ if (a == NULL || a->pub_key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -1233,14 +1175,14 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
if (*out == NULL) {
if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
- ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
new_buffer = 1;
}
if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
*out, buf_len, NULL)) {
- ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
if (new_buffer) {
OPENSSL_free(*out);
*out = NULL;
@@ -1252,20 +1194,16 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
return buf_len;
}
-ASN1_SEQUENCE(ECDSA_SIG) = {
- ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
-} static_ASN1_SEQUENCE_END(ECDSA_SIG)
+DECLARE_ASN1_FUNCTIONS(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG)
-DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
+#endif /* FIPS_MODULE */
ECDSA_SIG *ECDSA_SIG_new(void)
{
ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
if (sig == NULL)
- ECerr(EC_F_ECDSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return sig;
}
@@ -1278,6 +1216,75 @@ void ECDSA_SIG_free(ECDSA_SIG *sig)
OPENSSL_free(sig);
}
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len)
+{
+ ECDSA_SIG *sig;
+
+ if (len < 0)
+ return NULL;
+ if (psig != NULL && *psig != NULL) {
+ sig = *psig;
+ } else {
+ sig = ECDSA_SIG_new();
+ if (sig == NULL)
+ return NULL;
+ }
+ if (sig->r == NULL)
+ sig->r = BN_new();
+ if (sig->s == NULL)
+ sig->s = BN_new();
+ if (sig->r == NULL || sig->s == NULL
+ || ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
+ if (psig == NULL || *psig == NULL)
+ ECDSA_SIG_free(sig);
+ return NULL;
+ }
+ if (psig != NULL && *psig == NULL)
+ *psig = sig;
+ return sig;
+}
+
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **ppout)
+{
+ BUF_MEM *buf = NULL;
+ size_t encoded_len;
+ WPACKET pkt;
+
+ if (ppout == NULL) {
+ if (!WPACKET_init_null(&pkt, 0))
+ return -1;
+ } else if (*ppout == NULL) {
+ if ((buf = BUF_MEM_new()) == NULL
+ || !WPACKET_init_len(&pkt, buf, 0)) {
+ BUF_MEM_free(buf);
+ return -1;
+ }
+ } else {
+ if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
+ return -1;
+ }
+
+ if (!ossl_encode_der_dsa_sig(&pkt, sig->r, sig->s)
+ || !WPACKET_get_total_written(&pkt, &encoded_len)
+ || !WPACKET_finish(&pkt)) {
+ BUF_MEM_free(buf);
+ WPACKET_cleanup(&pkt);
+ return -1;
+ }
+
+ if (ppout != NULL) {
+ if (*ppout == NULL) {
+ *ppout = (unsigned char *)buf->data;
+ buf->data = NULL;
+ BUF_MEM_free(buf);
+ } else {
+ *ppout += encoded_len;
+ }
+ }
+
+ return (int)encoded_len;
+}
+
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != NULL)
@@ -1307,32 +1314,27 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
return 1;
}
-int ECDSA_size(const EC_KEY *r)
+int ECDSA_size(const EC_KEY *ec)
{
- int ret, i;
- ASN1_INTEGER bs;
- unsigned char buf[4];
+ int ret;
+ ECDSA_SIG sig;
const EC_GROUP *group;
+ const BIGNUM *bn;
- if (r == NULL)
+ if (ec == NULL)
return 0;
- group = EC_KEY_get0_group(r);
+ group = EC_KEY_get0_group(ec);
if (group == NULL)
return 0;
- i = EC_GROUP_order_bits(group);
- if (i == 0)
+ bn = EC_GROUP_get0_order(group);
+ if (bn == NULL)
return 0;
- bs.length = (i + 7) / 8;
- bs.data = buf;
- bs.type = V_ASN1_INTEGER;
- /* If the top bit is set the asn1 encoding is 1 larger. */
- buf[0] = 0xff;
-
- i = i2d_ASN1_INTEGER(&bs, NULL);
- i += i; /* r and s */
- ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+
+ sig.r = sig.s = (BIGNUM *)bn;
+ ret = i2d_ECDSA_SIG(&sig, NULL);
+
if (ret < 0)
- return 0;
+ ret = 0;
return ret;
}
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c
new file mode 100644
index 000000000000..cad576fc48a1
--- /dev/null
+++ b/crypto/ec/ec_backend.c
@@ -0,0 +1,836 @@
+/*
+ * Copyright 2020-2022 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
+ */
+
+/*
+ * Low level APIs related to EC_KEY are deprecated for public use,
+ * but still ok for internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <openssl/core_names.h>
+#include <openssl/objects.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#ifndef FIPS_MODULE
+# include <openssl/engine.h>
+# include <openssl/x509.h>
+#endif
+#include "crypto/bn.h"
+#include "crypto/ec.h"
+#include "ec_local.h"
+#include "e_os.h"
+#include "internal/param_build_set.h"
+
+/* Mapping between a flag and a name */
+static const OSSL_ITEM encoding_nameid_map[] = {
+ { OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT },
+ { OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP },
+};
+
+static const OSSL_ITEM check_group_type_nameid_map[] = {
+ { 0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT },
+ { EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED },
+ { EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST },
+};
+
+static const OSSL_ITEM format_nameid_map[] = {
+ { (int)POINT_CONVERSION_UNCOMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED },
+ { (int)POINT_CONVERSION_COMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED },
+ { (int)POINT_CONVERSION_HYBRID, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID },
+};
+
+int ossl_ec_encoding_name2id(const char *name)
+{
+ size_t i, sz;
+
+ /* Return the default value if there is no name */
+ if (name == NULL)
+ return OPENSSL_EC_NAMED_CURVE;
+
+ for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) {
+ if (OPENSSL_strcasecmp(name, encoding_nameid_map[i].ptr) == 0)
+ return encoding_nameid_map[i].id;
+ }
+ return -1;
+}
+
+static char *ec_param_encoding_id2name(int id)
+{
+ size_t i, sz;
+
+ for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) {
+ if (id == (int)encoding_nameid_map[i].id)
+ return encoding_nameid_map[i].ptr;
+ }
+ return NULL;
+}
+
+char *ossl_ec_check_group_type_id2name(int id)
+{
+ size_t i, sz;
+
+ for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) {
+ if (id == (int)check_group_type_nameid_map[i].id)
+ return check_group_type_nameid_map[i].ptr;
+ }
+ return NULL;
+}
+
+static int ec_check_group_type_name2id(const char *name)
+{
+ size_t i, sz;
+
+ /* Return the default value if there is no name */
+ if (name == NULL)
+ return 0;
+
+ for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) {
+ if (OPENSSL_strcasecmp(name, check_group_type_nameid_map[i].ptr) == 0)
+ return check_group_type_nameid_map[i].id;
+ }
+ return -1;
+}
+
+int ossl_ec_set_check_group_type_from_name(EC_KEY *ec, const char *name)
+{
+ int flags = ec_check_group_type_name2id(name);
+
+ if (flags == -1)
+ return 0;
+ EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK);
+ EC_KEY_set_flags(ec, flags);
+ return 1;
+}
+
+static int ec_set_check_group_type_from_param(EC_KEY *ec, const OSSL_PARAM *p)
+{
+ const char *name = NULL;
+ int status = 0;
+
+ switch (p->data_type) {
+ case OSSL_PARAM_UTF8_STRING:
+ name = p->data;
+ status = (name != NULL);
+ break;
+ case OSSL_PARAM_UTF8_PTR:
+ status = OSSL_PARAM_get_utf8_ptr(p, &name);
+ break;
+ }
+ if (status)
+ return ossl_ec_set_check_group_type_from_name(ec, name);
+ return 0;
+}
+
+int ossl_ec_pt_format_name2id(const char *name)
+{
+ size_t i, sz;
+
+ /* Return the default value if there is no name */
+ if (name == NULL)
+ return (int)POINT_CONVERSION_UNCOMPRESSED;
+
+ for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) {
+ if (OPENSSL_strcasecmp(name, format_nameid_map[i].ptr) == 0)
+ return format_nameid_map[i].id;
+ }
+ return -1;
+}
+
+char *ossl_ec_pt_format_id2name(int id)
+{
+ size_t i, sz;
+
+ for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) {
+ if (id == (int)format_nameid_map[i].id)
+ return format_nameid_map[i].ptr;
+ }
+ return NULL;
+}
+
+static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[], BN_CTX *bnctx,
+ unsigned char **genbuf)
+{
+ int ret = 0, fid;
+ const char *field_type;
+ const OSSL_PARAM *param = NULL;
+ const OSSL_PARAM *param_p = NULL;
+ const OSSL_PARAM *param_a = NULL;
+ const OSSL_PARAM *param_b = NULL;
+
+ fid = EC_GROUP_get_field_type(group);
+
+ if (fid == NID_X9_62_prime_field) {
+ field_type = SN_X9_62_prime_field;
+ } else if (fid == NID_X9_62_characteristic_two_field) {
+#ifdef OPENSSL_NO_EC2M
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+#else
+ field_type = SN_X9_62_characteristic_two_field;
+#endif
+ } else {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
+ return 0;
+ }
+
+ param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P);
+ param_a = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A);
+ param_b = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B);
+ if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL)
+ {
+ BIGNUM *p = BN_CTX_get(bnctx);
+ BIGNUM *a = BN_CTX_get(bnctx);
+ BIGNUM *b = BN_CTX_get(bnctx);
+
+ if (b == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_GROUP_get_curve(group, p, a, b, bnctx)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE);
+ goto err;
+ }
+ if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p)
+ || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a)
+ || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER);
+ if (tmpl != NULL || param != NULL) {
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+
+ if (order == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+ if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER,
+ order)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE);
+ if (tmpl != NULL || param != NULL) {
+ if (!ossl_param_build_set_utf8_string(tmpl, params,
+ OSSL_PKEY_PARAM_EC_FIELD_TYPE,
+ field_type)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR);
+ if (tmpl != NULL || param != NULL) {
+ size_t genbuf_len;
+ const EC_POINT *genpt = EC_GROUP_get0_generator(group);
+ point_conversion_form_t genform = EC_GROUP_get_point_conversion_form(group);
+
+ if (genpt == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR);
+ goto err;
+ }
+ genbuf_len = EC_POINT_point2buf(group, genpt, genform, genbuf, bnctx);
+ if (genbuf_len == 0) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR);
+ goto err;
+ }
+ if (!ossl_param_build_set_octet_string(tmpl, params,
+ OSSL_PKEY_PARAM_EC_GENERATOR,
+ *genbuf, genbuf_len)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR);
+ if (tmpl != NULL || param != NULL) {
+ const BIGNUM *cofactor = EC_GROUP_get0_cofactor(group);
+
+ if (cofactor != NULL
+ && !ossl_param_build_set_bn(tmpl, params,
+ OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED);
+ if (tmpl != NULL || param != NULL) {
+ unsigned char *seed = EC_GROUP_get0_seed(group);
+ size_t seed_len = EC_GROUP_get_seed_len(group);
+
+ if (seed != NULL
+ && seed_len > 0
+ && !ossl_param_build_set_octet_string(tmpl, params,
+ OSSL_PKEY_PARAM_EC_SEED,
+ seed, seed_len)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ ret = 1;
+err:
+ return ret;
+}
+
+int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[], OSSL_LIB_CTX *libctx,
+ const char *propq,
+ BN_CTX *bnctx, unsigned char **genbuf)
+{
+ int ret = 0, curve_nid, encoding_flag;
+ const char *encoding_name, *pt_form_name;
+ point_conversion_form_t genform;
+
+ if (group == NULL) {
+ ERR_raise(ERR_LIB_EC,EC_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ genform = EC_GROUP_get_point_conversion_form(group);
+ pt_form_name = ossl_ec_pt_format_id2name(genform);
+ if (pt_form_name == NULL
+ || !ossl_param_build_set_utf8_string(
+ tmpl, params,
+ OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM);
+ return 0;
+ }
+ encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE;
+ encoding_name = ec_param_encoding_id2name(encoding_flag);
+ if (encoding_name == NULL
+ || !ossl_param_build_set_utf8_string(tmpl, params,
+ OSSL_PKEY_PARAM_EC_ENCODING,
+ encoding_name)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (!ossl_param_build_set_int(tmpl, params,
+ OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS,
+ group->decoded_from_explicit_params))
+ return 0;
+
+ curve_nid = EC_GROUP_get_curve_name(group);
+
+ /*
+ * Get the explicit parameters in these two cases:
+ * - We do not have a template, i.e. specific parameters are requested
+ * - The curve is not a named curve
+ */
+ if (tmpl == NULL || curve_nid == NID_undef)
+ if (!ec_group_explicit_todata(group, tmpl, params, bnctx, genbuf))
+ goto err;
+
+ if (curve_nid != NID_undef) {
+ /* Named curve */
+ const char *curve_name = OSSL_EC_curve_nid2name(curve_nid);
+
+ if (curve_name == NULL
+ || !ossl_param_build_set_utf8_string(tmpl, params,
+ OSSL_PKEY_PARAM_GROUP_NAME,
+ curve_name)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE);
+ goto err;
+ }
+ }
+ ret = 1;
+err:
+ return ret;
+}
+
+/*
+ * The intention with the "backend" source file is to offer backend support
+ * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
+ * implementations alike.
+ */
+int ossl_ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode)
+{
+ const EC_GROUP *ecg = EC_KEY_get0_group(ec);
+ const BIGNUM *cofactor;
+ /*
+ * mode can be only 0 for disable, or 1 for enable here.
+ *
+ * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
+ * also supports mode == -1 with the meaning of "reset to the default for
+ * the associated key".
+ */
+ if (mode < 0 || mode > 1)
+ return 0;
+
+ if ((cofactor = EC_GROUP_get0_cofactor(ecg)) == NULL )
+ return 0;
+
+ /* ECDH cofactor mode has no effect if cofactor is 1 */
+ if (BN_is_one(cofactor))
+ return 1;
+
+ if (mode == 1)
+ EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
+ else if (mode == 0)
+ EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH);
+
+ return 1;
+}
+
+/*
+ * Callers of ossl_ec_key_fromdata MUST make sure that ec_key_params_fromdata has
+ * been called before!
+ *
+ * This function only gets the bare keypair, domain parameters and other
+ * parameters are treated separately, and domain parameters are required to
+ * define a keypair.
+ */
+int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private)
+{
+ const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL;
+ BN_CTX *ctx = NULL;
+ BIGNUM *priv_key = NULL;
+ unsigned char *pub_key = NULL;
+ size_t pub_key_len;
+ const EC_GROUP *ecg = NULL;
+ EC_POINT *pub_point = NULL;
+ int ok = 0;
+
+ ecg = EC_KEY_get0_group(ec);
+ if (ecg == NULL)
+ return 0;
+
+ param_pub_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
+ if (include_private)
+ param_priv_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+
+ ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
+ if (ctx == NULL)
+ goto err;
+
+ if (param_pub_key != NULL)
+ if (!OSSL_PARAM_get_octet_string(param_pub_key,
+ (void **)&pub_key, 0, &pub_key_len)
+ || (pub_point = EC_POINT_new(ecg)) == NULL
+ || !EC_POINT_oct2point(ecg, pub_point, pub_key, pub_key_len, ctx))
+ goto err;
+
+ if (param_priv_key != NULL && include_private) {
+ int fixed_words;
+ const BIGNUM *order;
+
+ /*
+ * 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.
+ */
+ order = EC_GROUP_get0_order(ecg);
+ if (order == NULL || BN_is_zero(order))
+ goto err;
+
+ fixed_words = bn_get_top(order) + 2;
+
+ if ((priv_key = BN_secure_new()) == NULL)
+ goto err;
+ if (bn_wexpand(priv_key, fixed_words) == NULL)
+ goto err;
+ BN_set_flags(priv_key, BN_FLG_CONSTTIME);
+
+ if (!OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+ goto err;
+ }
+
+ if (priv_key != NULL
+ && !EC_KEY_set_private_key(ec, priv_key))
+ goto err;
+
+ if (pub_point != NULL
+ && !EC_KEY_set_public_key(ec, pub_point))
+ goto err;
+
+ ok = 1;
+
+ err:
+ BN_CTX_free(ctx);
+ BN_clear_free(priv_key);
+ OPENSSL_free(pub_key);
+ EC_POINT_free(pub_point);
+ return ok;
+}
+
+int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
+{
+ int ok = 0;
+ EC_GROUP *group = NULL;
+
+ if (ec == NULL)
+ return 0;
+
+ group = EC_GROUP_new_from_params(params, ossl_ec_key_get_libctx(ec),
+ ossl_ec_key_get0_propq(ec));
+
+ if (!EC_KEY_set_group(ec, group))
+ goto err;
+ ok = 1;
+err:
+ EC_GROUP_free(group);
+ return ok;
+}
+
+static int ec_key_point_format_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+ int format = -1;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT);
+ if (p != NULL) {
+ if (!ossl_ec_pt_format_param2id(p, &format)) {
+ ECerr(0, EC_R_INVALID_FORM);
+ return 0;
+ }
+ EC_KEY_set_conv_form(ec, format);
+ }
+ return 1;
+}
+
+static int ec_key_group_check_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE);
+ if (p != NULL)
+ return ec_set_check_group_type_from_param(ec, p);
+ return 1;
+}
+
+static int ec_set_include_public(EC_KEY *ec, int include)
+{
+ int flags = EC_KEY_get_enc_flags(ec);
+
+ if (!include)
+ flags |= EC_PKEY_NO_PUBKEY;
+ else
+ flags &= ~EC_PKEY_NO_PUBKEY;
+ EC_KEY_set_enc_flags(ec, flags);
+ return 1;
+}
+
+int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ if (ec == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
+ if (p != NULL) {
+ int mode;
+
+ if (!OSSL_PARAM_get_int(p, &mode)
+ || !ossl_ec_set_ecdh_cofactor_mode(ec, mode))
+ return 0;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC);
+ if (p != NULL) {
+ int include = 1;
+
+ if (!OSSL_PARAM_get_int(p, &include)
+ || !ec_set_include_public(ec, include))
+ return 0;
+ }
+ if (!ec_key_point_format_fromdata(ec, params))
+ return 0;
+ if (!ec_key_group_check_fromdata(ec, params))
+ return 0;
+ return 1;
+}
+
+int ossl_ec_key_is_foreign(const EC_KEY *ec)
+{
+#ifndef FIPS_MODULE
+ if (ec->engine != NULL || EC_KEY_get_method(ec) != EC_KEY_OpenSSL())
+ return 1;
+#endif
+ return 0;
+
+}
+
+EC_KEY *ossl_ec_key_dup(const EC_KEY *src, int selection)
+{
+ EC_KEY *ret;
+
+ if (src == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if ((ret = ossl_ec_key_new_method_int(src->libctx, src->propq,
+ src->engine)) == NULL)
+ return NULL;
+
+ /* copy the parameters */
+ if (src->group != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+ ret->group = ossl_ec_group_new_ex(src->libctx, src->propq,
+ src->group->meth);
+ if (ret->group == NULL
+ || !EC_GROUP_copy(ret->group, src->group))
+ goto err;
+
+ if (src->meth != NULL)
+ ret->meth = src->meth;
+ }
+
+ /* copy the public key */
+ if (src->pub_key != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (ret->group == NULL)
+ /* no parameter-less keys allowed */
+ goto err;
+ ret->pub_key = EC_POINT_new(ret->group);
+ if (ret->pub_key == NULL
+ || !EC_POINT_copy(ret->pub_key, src->pub_key))
+ goto err;
+ }
+
+ /* copy the private key */
+ if (src->priv_key != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ if (ret->group == NULL)
+ /* no parameter-less keys allowed */
+ goto err;
+ ret->priv_key = BN_new();
+ if (ret->priv_key == NULL || !BN_copy(ret->priv_key, src->priv_key))
+ goto err;
+ if (ret->group->meth->keycopy
+ && ret->group->meth->keycopy(ret, src) == 0)
+ goto err;
+ }
+
+ /* copy the rest */
+ if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) {
+ ret->enc_flag = src->enc_flag;
+ ret->conv_form = src->conv_form;
+ }
+
+ ret->version = src->version;
+ ret->flags = src->flags;
+
+#ifndef FIPS_MODULE
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
+ &ret->ex_data, &src->ex_data))
+ goto err;
+#endif
+
+ if (ret->meth != NULL && ret->meth->copy != NULL) {
+ if ((selection
+ & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
+ goto err;
+ if (ret->meth->copy(ret, src) == 0)
+ goto err;
+ }
+
+ return ret;
+ err:
+ EC_KEY_free(ret);
+ return NULL;
+}
+
+int ossl_ec_encoding_param2id(const OSSL_PARAM *p, int *id)
+{
+ const char *name = NULL;
+ int status = 0;
+
+ switch (p->data_type) {
+ case OSSL_PARAM_UTF8_STRING:
+ /* The OSSL_PARAM functions have no support for this */
+ name = p->data;
+ status = (name != NULL);
+ break;
+ case OSSL_PARAM_UTF8_PTR:
+ status = OSSL_PARAM_get_utf8_ptr(p, &name);
+ break;
+ }
+ if (status) {
+ int i = ossl_ec_encoding_name2id(name);
+
+ if (i >= 0) {
+ *id = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int ossl_ec_pt_format_param2id(const OSSL_PARAM *p, int *id)
+{
+ const char *name = NULL;
+ int status = 0;
+
+ switch (p->data_type) {
+ case OSSL_PARAM_UTF8_STRING:
+ /* The OSSL_PARAM functions have no support for this */
+ name = p->data;
+ status = (name != NULL);
+ break;
+ case OSSL_PARAM_UTF8_PTR:
+ status = OSSL_PARAM_get_utf8_ptr(p, &name);
+ break;
+ }
+ if (status) {
+ int i = ossl_ec_pt_format_name2id(name);
+
+ if (i >= 0) {
+ *id = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifndef FIPS_MODULE
+int ossl_x509_algor_is_sm2(const X509_ALGOR *palg)
+{
+ int ptype = 0;
+ const void *pval = NULL;
+
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ if (ptype == V_ASN1_OBJECT)
+ return OBJ_obj2nid((ASN1_OBJECT *)pval) == NID_sm2;
+
+ if (ptype == V_ASN1_SEQUENCE) {
+ const ASN1_STRING *str = pval;
+ const unsigned char *der = str->data;
+ int derlen = str->length;
+ EC_GROUP *group;
+ int ret;
+
+ if ((group = d2i_ECPKParameters(NULL, &der, derlen)) == NULL)
+ ret = 0;
+ else
+ ret = (EC_GROUP_get_curve_name(group) == NID_sm2);
+
+ EC_GROUP_free(group);
+ return ret;
+ }
+
+ return 0;
+}
+
+EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ int ptype = 0;
+ const void *pval = NULL;
+ EC_KEY *eckey = NULL;
+ EC_GROUP *group = NULL;
+
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+ if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto ecerr;
+ }
+
+ if (ptype == V_ASN1_SEQUENCE) {
+ const ASN1_STRING *pstr = pval;
+ const unsigned char *pm = pstr->data;
+ int pmlen = pstr->length;
+
+
+ if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+ } else if (ptype == V_ASN1_OBJECT) {
+ const ASN1_OBJECT *poid = pval;
+
+ /*
+ * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
+ */
+
+ group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid));
+ if (group == NULL)
+ goto ecerr;
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto ecerr;
+ EC_GROUP_free(group);
+ } else {
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+
+ return eckey;
+
+ ecerr:
+ EC_KEY_free(eckey);
+ EC_GROUP_free(group);
+ return NULL;
+}
+
+EC_KEY *ossl_ec_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ const unsigned char *p = NULL;
+ int pklen;
+ EC_KEY *eckey = NULL;
+ const X509_ALGOR *palg;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf))
+ return 0;
+ eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq);
+ if (eckey == NULL)
+ goto err;
+
+ /* We have parameters now set private key */
+ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
+ goto err;
+ }
+
+ return eckey;
+ err:
+ EC_KEY_free(eckey);
+ return NULL;
+}
+#endif
diff --git a/crypto/ec/ec_check.c b/crypto/ec/ec_check.c
index d0706d2857e6..484124915dc6 100644
--- a/crypto/ec/ec_check.c
+++ b/crypto/ec/ec_check.c
@@ -1,22 +1,67 @@
/*
- * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include "ec_local.h"
#include <openssl/err.h>
+int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only,
+ BN_CTX *ctx)
+{
+ int nid;
+ BN_CTX *new_ctx = NULL;
+
+ if (group == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return NID_undef;
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new_ex(NULL);
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return NID_undef;
+ }
+ }
+
+ nid = ossl_ec_curve_nid_from_params(group, ctx);
+ if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL)
+ nid = NID_undef;
+
+ BN_CTX_free(new_ctx);
+ return nid;
+}
+
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
{
+#ifdef FIPS_MODULE
+ /*
+ * ECC domain parameter validation.
+ * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b.
+ */
+ return EC_GROUP_check_named_curve(group, 1, ctx) >= 0 ? 1 : 0;
+#else
int ret = 0;
const BIGNUM *order;
BN_CTX *new_ctx = NULL;
EC_POINT *point = NULL;
+ if (group == NULL || group->meth == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
/* Custom curves assumed to be correct */
if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
return 1;
@@ -24,24 +69,24 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
/* check the discriminant */
if (!EC_GROUP_check_discriminant(group, ctx)) {
- ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+ ERR_raise(ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO);
goto err;
}
/* check the generator */
if (group->generator == NULL) {
- ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
- ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
@@ -52,14 +97,14 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
if (order == NULL)
goto err;
if (BN_is_zero(order)) {
- ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_ORDER);
goto err;
}
if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
goto err;
if (!EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
@@ -69,4 +114,5 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
BN_CTX_free(new_ctx);
EC_POINT_free(point);
return ret;
+#endif /* FIPS_MODULE */
}
diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c
index b4c14e91e175..b5b2f3342dfb 100644
--- a/crypto/ec/ec_curve.c
+++ b/crypto/ec/ec_curve.c
@@ -2,12 +2,18 @@
* Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include "ec_local.h"
#include <openssl/err.h>
@@ -194,6 +200,7 @@ static const struct {
}
};
+# ifndef FIPS_MODULE
/* the x9.62 prime curves (minus the nist prime curves) */
static const struct {
EC_CURVE_DATA h;
@@ -372,6 +379,7 @@ static const struct {
0x43, 0x21, 0x46, 0x52, 0x65, 0x51
}
};
+#endif /* FIPS_MODULE */
static const struct {
EC_CURVE_DATA h;
@@ -411,6 +419,7 @@ static const struct {
}
};
+#ifndef FIPS_MODULE
/* the secg prime curves (minus the nist and x9.62 prime curves) */
static const struct {
EC_CURVE_DATA h;
@@ -832,10 +841,13 @@ static const struct {
0x5C, 0x5C, 0x2A, 0x3D
}
};
+#endif /* FIPS_MODULE */
#ifndef OPENSSL_NO_EC2M
/* characteristic two curves */
+
+# ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[20 + 15 * 6];
@@ -963,6 +975,7 @@ static const struct {
0x33, 0x04, 0x9B, 0xA9, 0x8F
}
};
+# endif /* FIPS_MODULE */
static const struct {
EC_CURVE_DATA h;
@@ -994,6 +1007,7 @@ static const struct {
}
};
+# ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 21 * 6];
@@ -1022,6 +1036,7 @@ static const struct {
0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B
}
};
+# endif /* FIPS_MODULE */
static const struct {
EC_CURVE_DATA h;
@@ -1052,6 +1067,7 @@ static const struct {
}
};
+# ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[20 + 25 * 6];
@@ -1127,6 +1143,7 @@ static const struct {
0xD5
}
};
+# endif /* FIPS_MODULE */
static const struct {
EC_CURVE_DATA h;
@@ -1137,6 +1154,7 @@ static const struct {
},
{
/* no seed */
+ /* p */
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
@@ -1201,6 +1219,7 @@ static const struct {
}
};
+#ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 30 * 6];
@@ -1210,6 +1229,7 @@ static const struct {
},
{
/* no seed */
+ /* p */
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
@@ -1235,6 +1255,7 @@ static const struct {
0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
}
};
+# endif /* FIPS_MODULE */
static const struct {
EC_CURVE_DATA h;
@@ -1245,6 +1266,7 @@ static const struct {
},
{
/* no seed */
+ /* p */
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
@@ -1279,7 +1301,7 @@ static const struct {
NID_X9_62_characteristic_two_field, 20, 36, 2
},
{
- /* no seed */
+ /* seed */
0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6,
0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
/* p */
@@ -1517,6 +1539,7 @@ static const struct {
}
};
+# ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[20 + 21 * 6];
@@ -2201,8 +2224,8 @@ static const struct {
0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E
}
};
-
-#endif
+# endif /* FIPS_MODULE */
+#endif /* OPENSSL_NO_EC2M */
/*
* These curves were added by Annie Yousar.
@@ -2212,6 +2235,7 @@ static const struct {
* generation mechanism is different from those defined in ANSI X9.62.
*/
+#ifndef FIPS_MODULE
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 20 * 6];
@@ -2751,8 +2775,9 @@ static const struct {
0x9C, 0xA9, 0x00, 0x69
}
};
+#endif /* FIPS_MODULE */
-#ifndef OPENSSL_NO_SM2
+#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE)
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 32 * 6];
@@ -2798,6 +2823,79 @@ typedef struct _ec_list_element_st {
const char *comment;
} ec_list_element;
+#ifdef FIPS_MODULE
+static const ec_list_element curve_list[] = {
+ /* prime field curves */
+ /* secg curves */
+ {NID_secp224r1, &_EC_NIST_PRIME_224.h,
+# if !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+ EC_GFp_nistp224_method,
+# else
+ 0,
+# endif
+ "NIST/SECG curve over a 224 bit prime field"},
+ /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
+ {NID_secp384r1, &_EC_NIST_PRIME_384.h,
+# if defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp384_method,
+# else
+ 0,
+# endif
+ "NIST/SECG curve over a 384 bit prime field"},
+
+ {NID_secp521r1, &_EC_NIST_PRIME_521.h,
+# if defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp521_method,
+# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+ EC_GFp_nistp521_method,
+# else
+ 0,
+# endif
+ "NIST/SECG curve over a 521 bit prime field"},
+
+ /* X9.62 curves */
+ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
+ "NIST/X9.62/SECG curve over a 192 bit prime field"},
+ {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
+# if defined(ECP_NISTZ256_ASM)
+ EC_GFp_nistz256_method,
+# elif defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp256_method,
+# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+ EC_GFp_nistp256_method,
+# else
+ 0,
+# endif
+ "X9.62/SECG curve over a 256 bit prime field"},
+
+# ifndef OPENSSL_NO_EC2M
+ /* characteristic two field curves */
+ /* NIST/SECG curves */
+ {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
+ "NIST/SECG/WTLS curve over a 163 bit binary field"},
+ {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
+ "NIST/SECG curve over a 163 bit binary field"},
+ {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+ {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+ {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
+ "NIST/SECG curve over a 283 bit binary field"},
+ {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
+ "NIST/SECG curve over a 283 bit binary field"},
+ {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
+ "NIST/SECG curve over a 409 bit binary field"},
+ {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
+ "NIST/SECG curve over a 409 bit binary field"},
+ {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
+ "NIST/SECG curve over a 571 bit binary field"},
+ {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
+ "NIST/SECG curve over a 571 bit binary field"},
+# endif
+};
+
+#else
+
static const ec_list_element curve_list[] = {
/* prime field curves */
/* secg curves */
@@ -2820,25 +2918,32 @@ static const ec_list_element curve_list[] = {
"SECG curve over a 192 bit prime field"},
{NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
"SECG curve over a 224 bit prime field"},
-#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
"NIST/SECG curve over a 224 bit prime field"},
-#else
+# else
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
"NIST/SECG curve over a 224 bit prime field"},
-#endif
+# endif
{NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
"SECG curve over a 256 bit prime field"},
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
- {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
+ {NID_secp384r1, &_EC_NIST_PRIME_384.h,
+# if defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp384_method,
+# else
+ 0,
+# endif
"NIST/SECG curve over a 384 bit prime field"},
-#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
- {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
- "NIST/SECG curve over a 521 bit prime field"},
-#else
- {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
+ {NID_secp521r1, &_EC_NIST_PRIME_521.h,
+# if defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp521_method,
+# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+ EC_GFp_nistp521_method,
+# else
+ 0,
+# endif
"NIST/SECG curve over a 521 bit prime field"},
-#endif
/* X9.62 curves */
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
"NIST/X9.62/SECG curve over a 192 bit prime field"},
@@ -2853,15 +2958,17 @@ static const ec_list_element curve_list[] = {
{NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
"X9.62 curve over a 239 bit prime field"},
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
-#if defined(ECP_NISTZ256_ASM)
+# if defined(ECP_NISTZ256_ASM)
EC_GFp_nistz256_method,
-#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+# elif defined(S390X_EC_ASM)
+ EC_GFp_s390x_nistp256_method,
+# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
EC_GFp_nistp256_method,
-#else
+# else
0,
-#endif
+# endif
"X9.62/SECG curve over a 256 bit prime field"},
-#ifndef OPENSSL_NO_EC2M
+# ifndef OPENSSL_NO_EC2M
/* characteristic two field curves */
/* NIST/SECG curves */
{NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
@@ -2945,7 +3052,7 @@ static const ec_list_element curve_list[] = {
"SECG curve over a 113 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
"X9.62 curve over a 163 bit binary field"},
-#endif
+# endif
{NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
"SECG/WTLS curve over a 112 bit prime field"},
{NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
@@ -2954,15 +3061,15 @@ static const ec_list_element curve_list[] = {
"WTLS curve over a 112 bit prime field"},
{NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
"WTLS curve over a 160 bit prime field"},
-#ifndef OPENSSL_NO_EC2M
+# ifndef OPENSSL_NO_EC2M
{NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
-#endif
+# endif
{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
"WTLS curve over a 224 bit prime field"},
-#ifndef OPENSSL_NO_EC2M
+# ifndef OPENSSL_NO_EC2M
/* IPSec curves */
{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
@@ -2970,7 +3077,7 @@ static const ec_list_element curve_list[] = {
{NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
-#endif
+# endif
/* brainpool curves */
{NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
"RFC 5639 curve over a 160 bit prime field"},
@@ -3000,15 +3107,32 @@ static const ec_list_element curve_list[] = {
"RFC 5639 curve over a 512 bit prime field"},
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
"RFC 5639 curve over a 512 bit prime field"},
-#ifndef OPENSSL_NO_SM2
+# ifndef OPENSSL_NO_SM2
{NID_sm2, &_EC_sm2p256v1.h, 0,
"SM2 curve over a 256 bit prime field"},
-#endif
+# endif
};
+#endif /* FIPS_MODULE */
#define curve_list_length OSSL_NELEM(curve_list)
-static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
+static const ec_list_element *ec_curve_nid2curve(int nid)
+{
+ size_t i;
+
+ if (nid <= 0)
+ return NULL;
+
+ for (i = 0; i < curve_list_length; i++) {
+ if (curve_list[i].nid == nid)
+ return &curve_list[i];
+ }
+ return NULL;
+}
+
+static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx,
+ const char *propq,
+ const ec_list_element curve)
{
EC_GROUP *group = NULL;
EC_POINT *P = NULL;
@@ -3023,10 +3147,11 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
/* If no curve data curve method must handle everything */
if (curve.data == NULL)
- return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL);
+ return ossl_ec_group_new_ex(libctx, propq,
+ curve.meth != NULL ? curve.meth() : NULL);
- if ((ctx = BN_CTX_new()) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
+ if ((ctx = BN_CTX_new_ex(libctx)) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -3039,20 +3164,20 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
|| (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL
|| (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (curve.meth != 0) {
meth = curve.meth();
- if (((group = EC_GROUP_new(meth)) == NULL) ||
+ if (((group = ossl_ec_group_new_ex(libctx, propq, meth)) == NULL) ||
(!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
} else if (data->field_type == NID_X9_62_prime_field) {
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -3061,7 +3186,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
* NID_X9_62_characteristic_two_field */
if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -3070,35 +3195,36 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
EC_GROUP_set_curve_name(group, curve.nid);
if ((P = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL
|| (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL
|| !BN_set_word(x, (BN_ULONG)data->cofactor)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (!EC_GROUP_set_generator(group, P, order, x)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (seed_len) {
if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
}
+#ifndef FIPS_MODULE
if (EC_GROUP_get_asn1_flag(group) == OPENSSL_EC_NAMED_CURVE) {
/*
* Some curves don't have an associated OID: for those we should not
@@ -3115,7 +3241,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
ASN1_OBJECT *asn1obj = OBJ_nid2obj(curve.nid);
if (asn1obj == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_OBJ_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB);
goto err;
}
if (OBJ_length(asn1obj) == 0)
@@ -3123,6 +3249,16 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
ASN1_OBJECT_free(asn1obj);
}
+#else
+ /*
+ * Inside the FIPS module we do not support explicit curves anyway
+ * so the above check is not necessary.
+ *
+ * Skipping it is also necessary because `OBJ_length()` and
+ * `ASN1_OBJECT_free()` are not available within the FIPS module
+ * boundaries.
+ */
+#endif
ok = 1;
err:
@@ -3141,28 +3277,33 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
return group;
}
-EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
+EC_GROUP *EC_GROUP_new_by_curve_name_ex(OSSL_LIB_CTX *libctx, const char *propq,
+ int nid)
{
- size_t i;
EC_GROUP *ret = NULL;
+ const ec_list_element *curve;
- if (nid <= 0)
- return NULL;
-
- for (i = 0; i < curve_list_length; i++)
- if (curve_list[i].nid == nid) {
- ret = ec_group_new_from_data(curve_list[i]);
- break;
- }
-
- if (ret == NULL) {
- ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
+ if ((curve = ec_curve_nid2curve(nid)) == NULL
+ || (ret = ec_group_new_from_data(libctx, propq, *curve)) == NULL) {
+#ifndef FIPS_MODULE
+ ERR_raise_data(ERR_LIB_EC, EC_R_UNKNOWN_GROUP,
+ "name=%s", OBJ_nid2sn(nid));
+#else
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP);
+#endif
return NULL;
}
return ret;
}
+#ifndef FIPS_MODULE
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
+{
+ return EC_GROUP_new_by_curve_name_ex(NULL, NULL, nid);
+}
+#endif
+
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
{
size_t i, min;
@@ -3180,49 +3321,14 @@ size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
return curve_list_length;
}
-/* Functions to translate between common NIST curve names and NIDs */
-
-typedef struct {
- const char *name; /* NIST Name of curve */
- int nid; /* Curve NID */
-} EC_NIST_NAME;
-
-static EC_NIST_NAME nist_curves[] = {
- {"B-163", NID_sect163r2},
- {"B-233", NID_sect233r1},
- {"B-283", NID_sect283r1},
- {"B-409", NID_sect409r1},
- {"B-571", NID_sect571r1},
- {"K-163", NID_sect163k1},
- {"K-233", NID_sect233k1},
- {"K-283", NID_sect283k1},
- {"K-409", NID_sect409k1},
- {"K-571", NID_sect571k1},
- {"P-192", NID_X9_62_prime192v1},
- {"P-224", NID_secp224r1},
- {"P-256", NID_X9_62_prime256v1},
- {"P-384", NID_secp384r1},
- {"P-521", NID_secp521r1}
-};
-
const char *EC_curve_nid2nist(int nid)
{
- size_t i;
- for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
- if (nist_curves[i].nid == nid)
- return nist_curves[i].name;
- }
- return NULL;
+ return ossl_ec_curve_nid2nist_int(nid);
}
int EC_curve_nist2nid(const char *name)
{
- size_t i;
- for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
- if (strcmp(nist_curves[i].name, name) == 0)
- return nist_curves[i].nid;
- }
- return NID_undef;
+ return ossl_ec_curve_nist2nid_int(name);
}
#define NUM_BN_FIELDS 6
@@ -3234,7 +3340,7 @@ int EC_curve_nist2nid(const char *name)
* Returns: The nid associated with the found named curve, or NID_undef
* if not found. If there was an error it returns -1.
*/
-int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
{
int ret = -1, nid, len, field_type, param_len;
size_t i, seed_len;
@@ -3242,17 +3348,13 @@ int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
unsigned char *param_bytes = NULL;
const EC_CURVE_DATA *data;
const EC_POINT *generator = NULL;
- const EC_METHOD *meth;
const BIGNUM *cofactor = NULL;
/* An array of BIGNUMs for (p, a, b, x, y, order) */
BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
- meth = EC_GROUP_method_of(group);
- if (meth == NULL)
- return -1;
/* Use the optional named curve nid as a search field */
nid = EC_GROUP_get_curve_name(group);
- field_type = EC_METHOD_get_field_type(meth);
+ field_type = EC_GROUP_get_field_type(group);
seed_len = EC_GROUP_get_seed_len(group);
seed = EC_GROUP_get0_seed(group);
cofactor = EC_GROUP_get0_cofactor(group);
diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c
index 944e317d9d14..1145bfb68f90 100644
--- a/crypto/ec/ec_cvt.c
+++ b/crypto/ec/ec_cvt.c
@@ -1,14 +1,21 @@
/*
- * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
+#include "crypto/bn.h"
#include "ec_local.h"
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
@@ -47,12 +54,12 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
meth = EC_GFp_mont_method();
#endif
- ret = EC_GROUP_new(meth);
+ ret = ossl_ec_group_new_ex(ossl_bn_get_libctx(ctx), NULL, meth);
if (ret == NULL)
return NULL;
if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) {
- EC_GROUP_clear_free(ret);
+ EC_GROUP_free(ret);
return NULL;
}
@@ -68,12 +75,12 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
meth = EC_GF2m_simple_method();
- ret = EC_GROUP_new(meth);
+ ret = ossl_ec_group_new_ex(ossl_bn_get_libctx(ctx), NULL, meth);
if (ret == NULL)
return NULL;
if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) {
- EC_GROUP_clear_free(ret);
+ EC_GROUP_free(ret);
return NULL;
}
diff --git a/crypto/ec/ec_deprecated.c b/crypto/ec/ec_deprecated.c
new file mode 100644
index 000000000000..765894c32977
--- /dev/null
+++ b/crypto/ec/ec_deprecated.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2002-2021 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
+ */
+
+/*
+ * Suppress deprecation warnings for EC low level implementations that are
+ * kept until removal.
+ */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
+ const EC_POINT *point,
+ point_conversion_form_t form,
+ BIGNUM *ret, BN_CTX *ctx)
+{
+ size_t buf_len = 0;
+ unsigned char *buf;
+
+ buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
+
+ if (buf_len == 0)
+ return NULL;
+
+ ret = BN_bin2bn(buf, buf_len, ret);
+
+ OPENSSL_free(buf);
+
+ return ret;
+}
+
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
+ const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
+{
+ size_t buf_len = 0;
+ unsigned char *buf;
+ EC_POINT *ret;
+
+ if ((buf_len = BN_num_bytes(bn)) == 0)
+ buf_len = 1;
+ if ((buf = OPENSSL_malloc(buf_len)) == NULL) {
+ ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (BN_bn2binpad(bn, buf, buf_len) < 0) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ if (point == NULL) {
+ if ((ret = EC_POINT_new(group)) == NULL) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+ } else
+ ret = point;
+
+ if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
+ if (ret != point)
+ EC_POINT_clear_free(ret);
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ OPENSSL_free(buf);
+ return ret;
+}
+#endif /* OPENSSL_NO_DEPRECATED_3_0 */
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index bfe74226503e..480376686b9e 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -1,8 +1,8 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -10,283 +10,11 @@
#include <openssl/err.h>
#include <openssl/ecerr.h>
+#include "crypto/ecerr.h"
-#ifndef OPENSSL_NO_ERR
+#ifndef OPENSSL_NO_EC
-static const ERR_STRING_DATA EC_str_functs[] = {
- {ERR_PACK(ERR_LIB_EC, EC_F_BN_TO_FELEM, 0), "BN_to_felem"},
- {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPARAMETERS, 0), "d2i_ECParameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPKPARAMETERS, 0), "d2i_ECPKParameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPRIVATEKEY, 0), "d2i_ECPrivateKey"},
- {ERR_PACK(ERR_LIB_EC, EC_F_DO_EC_KEY_PRINT, 0), "do_EC_KEY_print"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_DECRYPT, 0), "ecdh_cms_decrypt"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_SET_SHARED_INFO, 0),
- "ecdh_cms_set_shared_info"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_COMPUTE_KEY, 0), "ECDH_compute_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_SIMPLE_COMPUTE_KEY, 0),
- "ecdh_simple_compute_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_SIGN_EX, 0), "ECDSA_do_sign_ex"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_VERIFY, 0), "ECDSA_do_verify"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_EX, 0), "ECDSA_sign_ex"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_SETUP, 0), "ECDSA_sign_setup"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIG_NEW, 0), "ECDSA_SIG_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_VERIFY, 0), "ECDSA_verify"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECD_ITEM_VERIFY, 0), "ecd_item_verify"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM2TYPE, 0), "eckey_param2type"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM_DECODE, 0), "eckey_param_decode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_DECODE, 0), "eckey_priv_decode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_ENCODE, 0), "eckey_priv_encode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_DECODE, 0), "eckey_pub_decode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_ENCODE, 0), "eckey_pub_encode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_TYPE2PARAM, 0), "eckey_type2param"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT, 0), "ECParameters_print"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT_FP, 0),
- "ECParameters_print_fp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT, 0),
- "ECPKParameters_print"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT_FP, 0),
- "ECPKParameters_print_fp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_GET_AFFINE, 0),
- "ecp_nistz256_get_affine"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_INV_MOD_ORD, 0),
- "ecp_nistz256_inv_mod_ord"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, 0),
- "ecp_nistz256_mult_precompute"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_POINTS_MUL, 0),
- "ecp_nistz256_points_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_PRE_COMP_NEW, 0),
- "ecp_nistz256_pre_comp_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_WINDOWED_MUL, 0),
- "ecp_nistz256_windowed_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECX_KEY_OP, 0), "ecx_key_op"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PRIV_ENCODE, 0), "ecx_priv_encode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PUB_ENCODE, 0), "ecx_pub_encode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2CURVE, 0), "ec_asn1_group2curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2FIELDID, 0),
- "ec_asn1_group2fieldid"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0),
- "ec_GF2m_montgomery_point_multiply"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0),
- "ec_GF2m_simple_field_inv"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
- "ec_GF2m_simple_group_check_discriminant"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
- "ec_GF2m_simple_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_POST, 0),
- "ec_GF2m_simple_ladder_post"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_PRE, 0),
- "ec_GF2m_simple_ladder_pre"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_OCT2POINT, 0),
- "ec_GF2m_simple_oct2point"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT2OCT, 0),
- "ec_GF2m_simple_point2oct"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINTS_MUL, 0),
- "ec_GF2m_simple_points_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
- "ec_GF2m_simple_point_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0),
- "ec_GF2m_simple_point_set_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
- "ec_GF2m_simple_set_compressed_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_DECODE, 0),
- "ec_GFp_mont_field_decode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0),
- "ec_GFp_mont_field_encode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_INV, 0),
- "ec_GFp_mont_field_inv"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0),
- "ec_GFp_mont_field_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0),
- "ec_GFp_mont_field_set_to_one"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SQR, 0),
- "ec_GFp_mont_field_sqr"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_GROUP_SET_CURVE, 0),
- "ec_GFp_mont_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, 0),
- "ec_GFp_nistp224_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINTS_MUL, 0),
- "ec_GFp_nistp224_points_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, 0),
- "ec_GFp_nistp224_point_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, 0),
- "ec_GFp_nistp256_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINTS_MUL, 0),
- "ec_GFp_nistp256_points_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, 0),
- "ec_GFp_nistp256_point_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, 0),
- "ec_GFp_nistp521_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINTS_MUL, 0),
- "ec_GFp_nistp521_points_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, 0),
- "ec_GFp_nistp521_point_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_MUL, 0),
- "ec_GFp_nist_field_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_SQR, 0),
- "ec_GFp_nist_field_sqr"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0),
- "ec_GFp_nist_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0),
- "ec_GFp_simple_blind_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0),
- "ec_GFp_simple_field_inv"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
- "ec_GFp_simple_group_check_discriminant"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
- "ec_GFp_simple_group_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, 0),
- "ec_GFp_simple_make_affine"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_OCT2POINT, 0),
- "ec_GFp_simple_oct2point"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT2OCT, 0),
- "ec_GFp_simple_point2oct"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, 0),
- "ec_GFp_simple_points_make_affine"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
- "ec_GFp_simple_point_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0),
- "ec_GFp_simple_point_set_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
- "ec_GFp_simple_set_compressed_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK, 0), "EC_GROUP_check"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK_DISCRIMINANT, 0),
- "EC_GROUP_check_discriminant"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_COPY, 0), "EC_GROUP_copy"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE, 0), "EC_GROUP_get_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GF2M, 0),
- "EC_GROUP_get_curve_GF2m"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GFP, 0),
- "EC_GROUP_get_curve_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_DEGREE, 0), "EC_GROUP_get_degree"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPARAMETERS, 0),
- "EC_GROUP_get_ecparameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPKPARAMETERS, 0),
- "EC_GROUP_get_ecpkparameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 0),
- "EC_GROUP_get_pentanomial_basis"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 0),
- "EC_GROUP_get_trinomial_basis"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW, 0), "EC_GROUP_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_BY_CURVE_NAME, 0),
- "EC_GROUP_new_by_curve_name"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_DATA, 0),
- "ec_group_new_from_data"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, 0),
- "EC_GROUP_new_from_ecparameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, 0),
- "EC_GROUP_new_from_ecpkparameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE, 0), "EC_GROUP_set_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GF2M, 0),
- "EC_GROUP_set_curve_GF2m"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GFP, 0),
- "EC_GROUP_set_curve_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_GENERATOR, 0),
- "EC_GROUP_set_generator"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_SEED, 0), "EC_GROUP_set_seed"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_CHECK_KEY, 0), "EC_KEY_check_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_COPY, 0), "EC_KEY_copy"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_GENERATE_KEY, 0), "EC_KEY_generate_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW, 0), "EC_KEY_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW_METHOD, 0), "EC_KEY_new_method"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_OCT2PRIV, 0), "EC_KEY_oct2priv"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT, 0), "EC_KEY_print"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT_FP, 0), "EC_KEY_print_fp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2BUF, 0), "EC_KEY_priv2buf"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2OCT, 0), "EC_KEY_priv2oct"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 0),
- "EC_KEY_set_public_key_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_CHECK_KEY, 0),
- "ec_key_simple_check_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_OCT2PRIV, 0),
- "ec_key_simple_oct2priv"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_PRIV2OCT, 0),
- "ec_key_simple_priv2oct"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_CHECK, 0), "ec_pkey_check"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0),
- "EC_POINTs_make_affine"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MUL, 0), "EC_POINTs_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_COPY, 0), "EC_POINT_copy"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_DBL, 0), "EC_POINT_dbl"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES, 0),
- "EC_POINT_get_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 0),
- "EC_POINT_get_affine_coordinates_GF2m"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 0),
- "EC_POINT_get_affine_coordinates_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 0),
- "EC_POINT_get_Jprojective_coordinates_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_INVERT, 0), "EC_POINT_invert"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_AT_INFINITY, 0),
- "EC_POINT_is_at_infinity"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_ON_CURVE, 0),
- "EC_POINT_is_on_curve"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_MAKE_AFFINE, 0),
- "EC_POINT_make_affine"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_NEW, 0), "EC_POINT_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_OCT2POINT, 0), "EC_POINT_oct2point"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2BUF, 0), "EC_POINT_point2buf"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2OCT, 0), "EC_POINT_point2oct"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES, 0),
- "EC_POINT_set_affine_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0),
- "EC_POINT_set_affine_coordinates_GF2m"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 0),
- "EC_POINT_set_affine_coordinates_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 0),
- "EC_POINT_set_compressed_coordinates"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 0),
- "EC_POINT_set_compressed_coordinates_GF2m"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 0),
- "EC_POINT_set_compressed_coordinates_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 0),
- "EC_POINT_set_Jprojective_coordinates_GFp"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_TO_INFINITY, 0),
- "EC_POINT_set_to_infinity"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_PRE_COMP_NEW, 0), "ec_pre_comp_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_SCALAR_MUL_LADDER, 0),
- "ec_scalar_mul_ladder"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_MUL, 0), "ec_wNAF_mul"},
- {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_PRECOMPUTE_MULT, 0),
- "ec_wNAF_precompute_mult"},
- {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPARAMETERS, 0), "i2d_ECParameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPKPARAMETERS, 0), "i2d_ECPKParameters"},
- {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPRIVATEKEY, 0), "i2d_ECPrivateKey"},
- {ERR_PACK(ERR_LIB_EC, EC_F_I2O_ECPUBLICKEY, 0), "i2o_ECPublicKey"},
- {ERR_PACK(ERR_LIB_EC, EC_F_NISTP224_PRE_COMP_NEW, 0),
- "nistp224_pre_comp_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_NISTP256_PRE_COMP_NEW, 0),
- "nistp256_pre_comp_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_NISTP521_PRE_COMP_NEW, 0),
- "nistp521_pre_comp_new"},
- {ERR_PACK(ERR_LIB_EC, EC_F_O2I_ECPUBLICKEY, 0), "o2i_ECPublicKey"},
- {ERR_PACK(ERR_LIB_EC, EC_F_OLD_EC_PRIV_DECODE, 0), "old_ec_priv_decode"},
- {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDH_COMPUTE_KEY, 0),
- "ossl_ecdh_compute_key"},
- {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_SIGN_SIG, 0), "ossl_ecdsa_sign_sig"},
- {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_VERIFY_SIG, 0),
- "ossl_ecdsa_verify_sig"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_CTRL, 0), "pkey_ecd_ctrl"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN, 0), "pkey_ecd_digestsign"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN25519, 0),
- "pkey_ecd_digestsign25519"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0),
- "pkey_ecd_digestsign448"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_DERIVE, 0), "pkey_ec_derive"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_INIT, 0), "pkey_ec_init"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KDF_DERIVE, 0), "pkey_ec_kdf_derive"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"},
- {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"},
- {ERR_PACK(ERR_LIB_EC, EC_F_VALIDATE_ECX_DERIVE, 0), "validate_ecx_derive"},
- {0, NULL}
-};
+# ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA EC_str_reasons[] = {
{ERR_PACK(ERR_LIB_EC, 0, EC_R_ASN1_ERROR), "asn1 error"},
@@ -298,15 +26,19 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
"coordinates out of range"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
"curve does not support ecdh"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA),
+ "curve does not support ecdsa"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
"curve does not support signing"},
- {ERR_PACK(ERR_LIB_EC, 0, EC_R_D2I_ECPKPARAMETERS_FAILURE),
- "d2i ecpkparameters failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_DECODE_ERROR), "decode error"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_DISCRIMINANT_IS_ZERO),
"discriminant is zero"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
"ec group new by name failure"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED),
+ "explicit params not supported"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_FAILED_MAKING_PUBLIC_KEY),
+ "failed making public key"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_FIELD_TOO_LARGE), "field too large"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_GROUP2PKPARAMETERS_FAILURE),
@@ -315,7 +47,10 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
"i2d ecpkparameters failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS),
"incompatible objects"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_A), "invalid a"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_B), "invalid b"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COFACTOR), "invalid cofactor"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT),
"invalid compressed point"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT),
@@ -326,14 +61,20 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GENERATOR), "invalid generator"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_LENGTH), "invalid length"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_NAMED_GROUP_CONVERSION),
+ "invalid named group conversion"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH),
"invalid output length"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_P), "invalid p"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS),
"invalid pentanomial basis"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_SEED), "invalid seed"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS),
"invalid trinomial basis"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
@@ -356,8 +97,6 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
{ERR_PACK(ERR_LIB_EC, 0, EC_R_PASSED_NULL_PARAMETER),
"passed null parameter"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_PEER_KEY_ERROR), "peer key error"},
- {ERR_PACK(ERR_LIB_EC, 0, EC_R_PKPARAMETERS2GROUP_FAILURE),
- "pkparameters2group failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE),
"point arithmetic failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity"},
@@ -369,6 +108,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
"random number generation failed"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_SHARED_INFO_ERROR), "shared info error"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_SLOT_FULL), "slot full"},
+ {ERR_PACK(ERR_LIB_EC, 0, EC_R_TOO_MANY_RETRIES), "too many retries"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_GENERATOR), "undefined generator"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_ORDER), "undefined order"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
@@ -381,15 +121,16 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
{0, NULL}
};
-#endif
+# endif
-int ERR_load_EC_strings(void)
+int ossl_err_load_EC_strings(void)
{
-#ifndef OPENSSL_NO_ERR
- if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
- ERR_load_strings_const(EC_str_functs);
+# ifndef OPENSSL_NO_ERR
+ if (ERR_reason_error_string(EC_str_reasons[0].error) == NULL)
ERR_load_strings_const(EC_str_reasons);
- }
-#endif
+# endif
return 1;
}
+#else
+NON_EMPTY_TRANSLATION_UNIT
+#endif
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 63799002bc98..729d338b3379 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -2,31 +2,52 @@
* Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * EC_KEY low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include "internal/cryptlib.h"
#include <string.h>
#include "ec_local.h"
#include "internal/refcount.h"
#include <openssl/err.h>
-#include <openssl/engine.h>
+#ifndef FIPS_MODULE
+# include <openssl/engine.h>
+#endif
+#include <openssl/self_test.h>
+#include "prov/providercommon.h"
#include "crypto/bn.h"
+static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
+ void *cbarg);
+
+#ifndef FIPS_MODULE
EC_KEY *EC_KEY_new(void)
{
- return EC_KEY_new_method(NULL);
+ return ossl_ec_key_new_method_int(NULL, NULL, NULL);
}
+#endif
-EC_KEY *EC_KEY_new_by_curve_name(int nid)
+EC_KEY *EC_KEY_new_ex(OSSL_LIB_CTX *ctx, const char *propq)
{
- EC_KEY *ret = EC_KEY_new();
+ return ossl_ec_key_new_method_int(ctx, propq, NULL);
+}
+
+EC_KEY *EC_KEY_new_by_curve_name_ex(OSSL_LIB_CTX *ctx, const char *propq,
+ int nid)
+{
+ EC_KEY *ret = EC_KEY_new_ex(ctx, propq);
if (ret == NULL)
return NULL;
- ret->group = EC_GROUP_new_by_curve_name(nid);
+ ret->group = EC_GROUP_new_by_curve_name_ex(ctx, propq, nid);
if (ret->group == NULL) {
EC_KEY_free(ret);
return NULL;
@@ -39,6 +60,13 @@ EC_KEY *EC_KEY_new_by_curve_name(int nid)
return ret;
}
+#ifndef FIPS_MODULE
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+{
+ return EC_KEY_new_by_curve_name_ex(NULL, NULL, nid);
+}
+#endif
+
void EC_KEY_free(EC_KEY *r)
{
int i;
@@ -55,18 +83,21 @@ void EC_KEY_free(EC_KEY *r)
if (r->meth != NULL && r->meth->finish != NULL)
r->meth->finish(r);
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
ENGINE_finish(r->engine);
#endif
if (r->group && r->group->meth->keyfinish)
r->group->meth->keyfinish(r);
+#ifndef FIPS_MODULE
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
+#endif
CRYPTO_THREAD_lock_free(r->lock);
EC_GROUP_free(r->group);
EC_POINT_free(r->pub_key);
BN_clear_free(r->priv_key);
+ OPENSSL_free(r->propq);
OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
}
@@ -74,7 +105,7 @@ void EC_KEY_free(EC_KEY *r)
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
{
if (dest == NULL || src == NULL) {
- ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (src->meth != dest->meth) {
@@ -82,18 +113,19 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
dest->meth->finish(dest);
if (dest->group && dest->group->meth->keyfinish)
dest->group->meth->keyfinish(dest);
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
if (ENGINE_finish(dest->engine) == 0)
return 0;
dest->engine = NULL;
#endif
}
+ dest->libctx = src->libctx;
/* copy the parameters */
if (src->group != NULL) {
- const EC_METHOD *meth = EC_GROUP_method_of(src->group);
/* clear the old group */
EC_GROUP_free(dest->group);
- dest->group = EC_GROUP_new(meth);
+ dest->group = ossl_ec_group_new_ex(src->libctx, src->propq,
+ src->group->meth);
if (dest->group == NULL)
return NULL;
if (!EC_GROUP_copy(dest->group, src->group))
@@ -129,12 +161,14 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
dest->conv_form = src->conv_form;
dest->version = src->version;
dest->flags = src->flags;
+#ifndef FIPS_MODULE
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
&dest->ex_data, &src->ex_data))
return NULL;
+#endif
if (src->meth != dest->meth) {
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
if (src->engine != NULL && ENGINE_init(src->engine) == 0)
return NULL;
dest->engine = src->engine;
@@ -145,21 +179,14 @@ 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;
}
EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
{
- EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
-
- if (ret == NULL)
- return NULL;
-
- if (EC_KEY_copy(ret, ec_key) == NULL) {
- EC_KEY_free(ret);
- return NULL;
- }
- return ret;
+ return ossl_ec_key_dup(ec_key, OSSL_KEYMGMT_SELECT_ALL);
}
int EC_KEY_up_ref(EC_KEY *r)
@@ -182,156 +209,389 @@ ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
int EC_KEY_generate_key(EC_KEY *eckey)
{
if (eckey == NULL || eckey->group == NULL) {
- ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if (eckey->meth->keygen != NULL)
- return eckey->meth->keygen(eckey);
- ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
+ if (eckey->meth->keygen != NULL) {
+ int ret;
+
+ ret = eckey->meth->keygen(eckey);
+ if (ret == 1)
+ eckey->dirty_cnt++;
+
+ return ret;
+ }
+ ERR_raise(ERR_LIB_EC, 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;
}
-int ec_key_simple_generate_key(EC_KEY *eckey)
+/*
+ * ECC Key generation.
+ * 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.
+ */
+static int ec_generate_key(EC_KEY *eckey, int pairwise_test)
{
int ok = 0;
- BN_CTX *ctx = NULL;
BIGNUM *priv_key = NULL;
- const BIGNUM *order = NULL;
+ const BIGNUM *tmp = NULL;
+ BIGNUM *order = NULL;
EC_POINT *pub_key = NULL;
+ const EC_GROUP *group = eckey->group;
+ BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx);
+ int sm2 = EC_KEY_get_flags(eckey) & EC_FLAG_SM2_RANGE ? 1 : 0;
- if ((ctx = BN_CTX_new()) == NULL)
+ if (ctx == NULL)
goto err;
if (eckey->priv_key == NULL) {
- priv_key = BN_new();
+ priv_key = BN_secure_new();
if (priv_key == NULL)
goto err;
} else
priv_key = eckey->priv_key;
- order = EC_GROUP_get0_order(eckey->group);
- if (order == NULL)
+ /*
+ * Steps (1-2): Check domain parameters and security strength.
+ * These steps must be done by the user. This would need to be
+ * stated in the security policy.
+ */
+
+ tmp = EC_GROUP_get0_order(group);
+ if (tmp == NULL)
goto err;
+ /*
+ * Steps (3-7): priv_key = DRBG_RAND(order_n_bits) (range [1, n-1]).
+ * Although this is slightly different from the standard, it is effectively
+ * equivalent as it gives an unbiased result ranging from 1..n-1. It is also
+ * faster as the standard needs to retry more often. Also doing
+ * 1 + rand[0..n-2] would effect the way that tests feed dummy entropy into
+ * rand so the simpler backward compatible method has been used here.
+ */
+
+ /* range of SM2 private key is [1, n-1) */
+ if (sm2) {
+ order = BN_new();
+ if (order == NULL || !BN_sub(order, tmp, BN_value_one()))
+ goto err;
+ } else {
+ order = BN_dup(tmp);
+ if (order == NULL)
+ goto err;
+ }
+
do
- if (!BN_priv_rand_range(priv_key, order))
+ if (!BN_priv_rand_range_ex(priv_key, order, 0, ctx))
goto err;
while (BN_is_zero(priv_key)) ;
if (eckey->pub_key == NULL) {
- pub_key = EC_POINT_new(eckey->group);
+ pub_key = EC_POINT_new(group);
if (pub_key == NULL)
goto err;
} else
pub_key = eckey->pub_key;
- if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+ /* Step (8) : pub_key = priv_key * G (where G is a point on the curve) */
+ if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
goto err;
eckey->priv_key = priv_key;
eckey->pub_key = pub_key;
+ priv_key = NULL;
+ pub_key = NULL;
+
+ eckey->dirty_cnt++;
+
+#ifdef FIPS_MODULE
+ pairwise_test = 1;
+#endif /* FIPS_MODULE */
ok = 1;
+ if (pairwise_test) {
+ OSSL_CALLBACK *cb = NULL;
+ void *cbarg = NULL;
- err:
- if (eckey->pub_key == NULL)
- EC_POINT_free(pub_key);
- if (eckey->priv_key != priv_key)
- BN_free(priv_key);
+ OSSL_SELF_TEST_get_callback(eckey->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) {
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+ BN_clear(eckey->priv_key);
+ if (eckey->pub_key != NULL)
+ EC_POINT_set_to_infinity(group, eckey->pub_key);
+ }
+
+ EC_POINT_free(pub_key);
+ BN_clear_free(priv_key);
BN_CTX_free(ctx);
+ BN_free(order);
return ok;
}
-int ec_key_simple_generate_public_key(EC_KEY *eckey)
+int ossl_ec_key_simple_generate_key(EC_KEY *eckey)
{
- return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
- NULL, NULL);
+ return ec_generate_key(eckey, 0);
+}
+
+int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey)
+{
+ int ret;
+ BN_CTX *ctx = BN_CTX_new_ex(eckey->libctx);
+
+ if (ctx == NULL)
+ return 0;
+
+ /*
+ * See SP800-56AR3 5.6.1.2.2: Step (8)
+ * pub_key = priv_key * G (where G is a point on the curve)
+ */
+ ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
+ NULL, ctx);
+
+ BN_CTX_free(ctx);
+ if (ret == 1)
+ eckey->dirty_cnt++;
+
+ return ret;
}
int EC_KEY_check_key(const EC_KEY *eckey)
{
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
- ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (eckey->group->meth->keycheck == NULL) {
- ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return eckey->group->meth->keycheck(eckey);
}
-int ec_key_simple_check_key(const EC_KEY *eckey)
+/*
+ * Check the range of the EC public key.
+ * See SP800-56A R3 Section 5.6.2.3.3 (Part 2)
+ * i.e.
+ * - If q = odd prime p: Verify that xQ and yQ are integers in the
+ * interval[0, p - 1], OR
+ * - If q = 2m: Verify that xQ and yQ are bit strings of length m bits.
+ * Returns 1 if the public key has a valid range, otherwise it returns 0.
+ */
+static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key)
{
- int ok = 0;
- BN_CTX *ctx = NULL;
- const BIGNUM *order = NULL;
- EC_POINT *point = NULL;
+ int ret = 0;
+ BIGNUM *x, *y;
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL)
+ goto err;
+
+ if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx))
+ goto err;
+
+ if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) {
+ if (BN_is_negative(x)
+ || BN_cmp(x, key->group->field) >= 0
+ || BN_is_negative(y)
+ || BN_cmp(y, key->group->field) >= 0) {
+ goto err;
+ }
+ } else {
+ int m = EC_GROUP_get_degree(key->group);
+ if (BN_num_bits(x) > m || BN_num_bits(y) > m) {
+ goto err;
+ }
+ }
+ ret = 1;
+err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+/*
+ * ECC Partial Public-Key Validation as specified in SP800-56A R3
+ * Section 5.6.2.3.4 ECC Partial Public-Key Validation Routine.
+ */
+int ossl_ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx)
+{
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+ /* 5.6.2.3.3 (Step 1): Q != infinity */
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
- goto err;
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
+ return 0;
}
- if ((ctx = BN_CTX_new()) == NULL)
- goto err;
- if ((point = EC_POINT_new(eckey->group)) == NULL)
- goto err;
+ /* 5.6.2.3.3 (Step 2) Test if the public key is in range */
+ if (!ec_key_public_range_check(ctx, eckey)) {
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
+ return 0;
+ }
- /* testing whether the pub_key is on the elliptic curve */
+ /* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE);
+ return 0;
}
- /* testing whether pub_key * order is the point at infinity */
+ return 1;
+}
+
+/*
+ * ECC Key validation as specified in SP800-56A R3.
+ * Section 5.6.2.3.3 ECC Full Public-Key Validation Routine.
+ */
+int ossl_ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
+{
+ int ret = 0;
+ EC_POINT *point = NULL;
+ const BIGNUM *order = NULL;
+
+ if (!ossl_ec_key_public_check_quick(eckey, ctx))
+ return 0;
+
+ point = EC_POINT_new(eckey->group);
+ if (point == NULL)
+ return 0;
+
order = eckey->group->order;
if (BN_is_zero(order)) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
+ /* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_ORDER);
goto err;
}
- /*
- * in case the priv_key is present : check if generator * priv_key ==
- * pub_key
- */
+ ret = 1;
+err:
+ EC_POINT_free(point);
+ return ret;
+}
+
+/*
+ * ECC Key validation as specified in SP800-56A R3.
+ * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
+ * The private key is in the range [1, order-1]
+ */
+int ossl_ec_key_private_check(const EC_KEY *eckey)
+{
+ if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
+ || BN_cmp(eckey->priv_key, eckey->group->order) >= 0) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * ECC Key validation as specified in SP800-56A R3.
+ * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
+ * Check if generator * priv_key = pub_key
+ */
+int ossl_ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx)
+{
+ int ret = 0;
+ EC_POINT *point = NULL;
+
+ if (eckey == NULL
+ || eckey->group == NULL
+ || eckey->pub_key == NULL
+ || eckey->priv_key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ point = EC_POINT_new(eckey->group);
+ if (point == NULL)
+ goto err;
+
+
+ if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
+ goto err;
+ }
+ ret = 1;
+err:
+ EC_POINT_free(point);
+ return ret;
+}
+
+
+/*
+ * ECC Key validation as specified in SP800-56A R3.
+ * Section 5.6.2.3.3 ECC Full Public-Key Validation
+ * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
+ * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency
+ * NOTES:
+ * Before calling this method in fips mode, there should be an assurance that
+ * an approved elliptic-curve group is used.
+ * Returns 1 if the key is valid, otherwise it returns 0.
+ */
+int ossl_ec_key_simple_check_key(const EC_KEY *eckey)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+
+ if (eckey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL)
+ return 0;
+
+ if (!ossl_ec_key_public_check(eckey, ctx))
+ goto err;
+
if (eckey->priv_key != NULL) {
- if (BN_cmp(eckey->priv_key, order) >= 0) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
- goto err;
- }
- if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
- NULL, NULL, ctx)) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
+ if (!ossl_ec_key_private_check(eckey)
+ || !ossl_ec_key_pairwise_check(eckey, ctx))
goto err;
- }
- if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
- ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
- goto err;
- }
}
ok = 1;
- err:
+err:
BN_CTX_free(ctx);
- EC_POINT_free(point);
return ok;
}
@@ -344,11 +604,10 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
int ok = 0;
if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
- ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
- ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(key->libctx);
if (ctx == NULL)
return 0;
@@ -369,17 +628,15 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
goto err;
/*
- * Check if retrieved coordinates match originals and are less than field
- * order: if not values are out of range.
+ * Check if retrieved coordinates match originals. The range check is done
+ * inside EC_KEY_check_key().
*/
- if (BN_cmp(x, tx) || BN_cmp(y, ty)
- || (BN_cmp(x, key->group->field) >= 0)
- || (BN_cmp(y, key->group->field) >= 0)) {
- ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
- EC_R_COORDINATES_OUT_OF_RANGE);
+ if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
+ /* EC_KEY_set_public_key updates dirty_cnt */
if (!EC_KEY_set_public_key(key, point))
goto err;
@@ -396,6 +653,22 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
}
+OSSL_LIB_CTX *ossl_ec_key_get_libctx(const EC_KEY *key)
+{
+ return key->libctx;
+}
+
+const char *ossl_ec_key_get0_propq(const EC_KEY *key)
+{
+ return key->propq;
+}
+
+void ossl_ec_key_set0_libctx(EC_KEY *key, OSSL_LIB_CTX *libctx)
+{
+ key->libctx = libctx;
+ /* Do we need to propagate this to the group? */
+}
+
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
{
return key->group;
@@ -407,6 +680,10 @@ 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);
+ if (key->group != NULL && EC_GROUP_get_curve_name(key->group) == NID_sm2)
+ EC_KEY_set_flags(key, EC_FLAG_SM2_RANGE);
+
+ key->dirty_cnt++;
return (key->group == NULL) ? 0 : 1;
}
@@ -505,6 +782,7 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
BN_clear_free(key->priv_key);
key->priv_key = tmp_key;
+ key->dirty_cnt++;
return 1;
}
@@ -521,6 +799,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;
}
@@ -552,12 +831,14 @@ void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
EC_GROUP_set_asn1_flag(key->group, flag);
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
{
if (key->group == NULL)
return 0;
return EC_GROUP_precompute_mult(key->group, ctx);
}
+#endif
int EC_KEY_get_flags(const EC_KEY *key)
{
@@ -567,11 +848,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++;
}
int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
@@ -600,6 +883,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
@@ -618,15 +902,15 @@ size_t EC_KEY_priv2oct(const EC_KEY *eckey,
if (eckey->group == NULL || eckey->group->meth == NULL)
return 0;
if (eckey->group->meth->priv2oct == NULL) {
- ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return eckey->group->meth->priv2oct(eckey, buf, len);
}
-size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
- unsigned char *buf, size_t len)
+size_t ossl_ec_key_simple_priv2oct(const EC_KEY *eckey,
+ unsigned char *buf, size_t len)
{
size_t buf_len;
@@ -641,7 +925,7 @@ size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
/* Octetstring may need leading zeros if BN is to short */
if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
- ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -650,27 +934,34 @@ 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);
+ ERR_raise(ERR_LIB_EC, 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)
+int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf,
+ size_t len)
{
if (eckey->priv_key == NULL)
eckey->priv_key = BN_secure_new();
if (eckey->priv_key == NULL) {
- ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) {
- ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
+ eckey->dirty_cnt++;
return 1;
}
@@ -683,7 +974,7 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
if (len == 0)
return 0;
if ((buf = OPENSSL_malloc(len)) == NULL) {
- ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
len = EC_KEY_priv2oct(eckey, buf, len);
@@ -702,3 +993,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;
+}
diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c
index 53a4a9295201..8c011635cb42 100644
--- a/crypto/ec/ec_kmeth.c
+++ b/crypto/ec/ec_kmeth.c
@@ -1,15 +1,23 @@
/*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDH and ECDSA low level APIs are deprecated for public use, but still ok
+ * for internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include <openssl/ec.h>
-#include <openssl/engine.h>
+#ifndef FIPS_MODULE
+# include <openssl/engine.h>
+#endif
#include <openssl/err.h>
#include "ec_local.h"
@@ -59,7 +67,7 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
if (finish != NULL)
finish(key);
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
ENGINE_finish(key->engine);
key->engine = NULL;
#endif
@@ -70,28 +78,37 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
return 1;
}
-EC_KEY *EC_KEY_new_method(ENGINE *engine)
+EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq,
+ ENGINE *engine)
{
EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ ret->libctx = libctx;
+ if (propq != NULL) {
+ ret->propq = OPENSSL_strdup(propq);
+ if (ret->propq == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
ret->references = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(ret);
- return NULL;
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
}
ret->meth = EC_KEY_get_default_method();
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
if (engine != NULL) {
if (!ENGINE_init(engine)) {
- ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB);
goto err;
}
ret->engine = engine;
@@ -100,7 +117,7 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
if (ret->engine != NULL) {
ret->meth = ENGINE_get_EC(ret->engine);
if (ret->meth == NULL) {
- ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB);
goto err;
}
}
@@ -109,12 +126,15 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
ret->version = 1;
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+/* No ex_data inside the FIPS provider */
+#ifndef FIPS_MODULE
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
goto err;
}
+#endif
if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
- ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL);
+ ERR_raise(ERR_LIB_EC, ERR_R_INIT_FAIL);
goto err;
}
return ret;
@@ -124,6 +144,13 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
return NULL;
}
+#ifndef FIPS_MODULE
+EC_KEY *EC_KEY_new_method(ENGINE *engine)
+{
+ return ossl_ec_key_new_method_int(NULL, NULL, engine);
+}
+#endif
+
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
const EC_KEY *eckey,
void *(*KDF) (const void *in, size_t inlen, void *out,
@@ -132,11 +159,11 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
unsigned char *sec = NULL;
size_t seclen;
if (eckey->meth->compute_key == NULL) {
- ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
}
if (outlen > INT_MAX) {
- ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH);
return 0;
}
if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 08db89fceeb5..a082876fb479 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -1,41 +1,59 @@
/*
- * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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>
+/*
+ * EC_GROUP low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+#include <string.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/opensslv.h>
-
+#include "crypto/ec.h"
+#include "crypto/bn.h"
+#include "internal/nelem.h"
#include "ec_local.h"
/* functions for EC_GROUP objects */
-EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
+EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
+ const EC_METHOD *meth)
{
EC_GROUP *ret;
if (meth == NULL) {
- ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
+ ERR_raise(ERR_LIB_EC, EC_R_SLOT_FULL);
return NULL;
}
if (meth->group_init == 0) {
- ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ ret->libctx = libctx;
+ if (propq != NULL) {
+ ret->propq = OPENSSL_strdup(propq);
+ if (ret->propq == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
ret->meth = meth;
if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
ret->order = BN_new();
@@ -45,7 +63,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
if (ret->cofactor == NULL)
goto err;
}
- ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
+ ret->asn1_flag = OPENSSL_EC_EXPLICIT_CURVE;
ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
if (!meth->group_init(ret))
goto err;
@@ -54,10 +72,20 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
err:
BN_free(ret->order);
BN_free(ret->cofactor);
+ OPENSSL_free(ret->propq);
OPENSSL_free(ret);
return NULL;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+# ifndef FIPS_MODULE
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
+{
+ return ossl_ec_group_new_ex(NULL, NULL, meth);
+}
+# endif
+#endif
+
void EC_pre_comp_free(EC_GROUP *group)
{
switch (group->pre_comp_type) {
@@ -105,9 +133,11 @@ void EC_GROUP_free(EC_GROUP *group)
BN_free(group->order);
BN_free(group->cofactor);
OPENSSL_free(group->seed);
+ OPENSSL_free(group->propq);
OPENSSL_free(group);
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
void EC_GROUP_clear_free(EC_GROUP *group)
{
if (!group)
@@ -126,20 +156,22 @@ void EC_GROUP_clear_free(EC_GROUP *group)
OPENSSL_clear_free(group->seed, group->seed_len);
OPENSSL_clear_free(group, sizeof(*group));
}
+#endif
int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
{
if (dest->meth->group_copy == 0) {
- ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth) {
- ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == src)
return 1;
+ dest->libctx = src->libctx;
dest->curve_name = src->curve_name;
/* Copy precomputed */
@@ -216,7 +248,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
if (src->seed) {
OPENSSL_free(dest->seed);
if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) {
- ECerr(EC_F_EC_GROUP_COPY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!memcpy(dest->seed, src->seed, src->seed_len))
@@ -239,7 +271,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
if (a == NULL)
return NULL;
- if ((t = EC_GROUP_new(a->meth)) == NULL)
+ if ((t = ossl_ec_group_new_ex(a->libctx, a->propq, a->meth)) == NULL)
return NULL;
if (!EC_GROUP_copy(t, a))
goto err;
@@ -254,6 +286,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
return t;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
{
return group->meth;
@@ -263,6 +296,7 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
{
return meth->field_type;
}
+#endif
static int ec_precompute_mont_data(EC_GROUP *);
@@ -295,7 +329,7 @@ static int ec_guess_cofactor(EC_GROUP *group) {
return 1;
}
- if ((ctx = BN_CTX_new()) == NULL)
+ if ((ctx = BN_CTX_new_ex(group->libctx)) == NULL)
return 0;
BN_CTX_start(ctx);
@@ -331,14 +365,14 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor)
{
if (generator == NULL) {
- ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/* require group->field >= 1 */
if (group->field == NULL || BN_is_zero(group->field)
|| BN_is_negative(group->field)) {
- ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
return 0;
}
@@ -349,7 +383,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
*/
if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
|| BN_num_bits(order) > BN_num_bits(group->field) + 1) {
- ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
return 0;
}
@@ -359,7 +393,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
* So accept cofactor == NULL or cofactor >= 0.
*/
if (cofactor != NULL && BN_is_negative(cofactor)) {
- ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR);
return 0;
}
@@ -447,6 +481,10 @@ const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
{
group->curve_name = nid;
+ group->asn1_flag =
+ (nid != NID_undef)
+ ? OPENSSL_EC_NAMED_CURVE
+ : OPENSSL_EC_EXPLICIT_CURVE;
}
int EC_GROUP_get_curve_name(const EC_GROUP *group)
@@ -454,6 +492,16 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group)
return group->curve_name;
}
+const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group)
+{
+ return group->field;
+}
+
+int EC_GROUP_get_field_type(const EC_GROUP *group)
+{
+ return group->meth->field_type;
+}
+
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
{
group->asn1_flag = flag;
@@ -486,7 +534,7 @@ size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
return 1;
if ((group->seed = OPENSSL_malloc(len)) == NULL) {
- ECerr(EC_F_EC_GROUP_SET_SEED, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(group->seed, p, len);
@@ -509,7 +557,7 @@ int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx)
{
if (group->meth->group_set_curve == 0) {
- ECerr(EC_F_EC_GROUP_SET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_set_curve(group, p, a, b, ctx);
@@ -519,13 +567,13 @@ int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
BN_CTX *ctx)
{
if (group->meth->group_get_curve == NULL) {
- ECerr(EC_F_EC_GROUP_GET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_curve(group, p, a, b, ctx);
}
-#if OPENSSL_API_COMPAT < 0x10200000L
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx)
{
@@ -556,7 +604,7 @@ int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
int EC_GROUP_get_degree(const EC_GROUP *group)
{
if (group->meth->group_get_degree == 0) {
- ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_degree(group);
@@ -565,8 +613,7 @@ int EC_GROUP_get_degree(const EC_GROUP *group)
int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
{
if (group->meth->group_check_discriminant == 0) {
- ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_check_discriminant(group, ctx);
@@ -576,11 +623,12 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
{
int r = 0;
BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+#ifndef FIPS_MODULE
BN_CTX *ctx_new = NULL;
+#endif
/* compare the field types */
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
- EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+ if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b))
return 1;
/* compare the curve name (if present in both) */
if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
@@ -589,8 +637,10 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
return 0;
+#ifndef FIPS_MODULE
if (ctx == NULL)
ctx_new = ctx = BN_CTX_new();
+#endif
if (ctx == NULL)
return -1;
@@ -603,7 +653,9 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
b3 = BN_CTX_get(ctx);
if (b3 == NULL) {
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(ctx_new);
+#endif
return -1;
}
@@ -615,33 +667,47 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
!b->meth->group_get_curve(b, b1, b2, b3, ctx))
r = 1;
- if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+ /* return 1 if the curve parameters are different */
+ if (r || BN_cmp(a1, b1) != 0 || BN_cmp(a2, b2) != 0 || BN_cmp(a3, b3) != 0)
r = 1;
/* XXX EC_POINT_cmp() assumes that the methods are equal */
+ /* return 1 if the generators are different */
if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
- EC_GROUP_get0_generator(b), ctx))
+ EC_GROUP_get0_generator(b), ctx) != 0)
r = 1;
if (!r) {
const BIGNUM *ao, *bo, *ac, *bc;
- /* compare the order and cofactor */
+ /* compare the orders */
ao = EC_GROUP_get0_order(a);
bo = EC_GROUP_get0_order(b);
- ac = EC_GROUP_get0_cofactor(a);
- bc = EC_GROUP_get0_cofactor(b);
if (ao == NULL || bo == NULL) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx_new);
- return -1;
+ /* return an error if either order is NULL */
+ r = -1;
+ goto end;
}
- if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
+ if (BN_cmp(ao, bo) != 0) {
+ /* return 1 if orders are different */
r = 1;
+ goto end;
+ }
+ /*
+ * It gets here if the curve parameters and generator matched.
+ * Now check the optional cofactors (if both are present).
+ */
+ ac = EC_GROUP_get0_cofactor(a);
+ bc = EC_GROUP_get0_cofactor(b);
+ /* Returns 1 (mismatch) if both cofactors are specified and different */
+ if (!BN_is_zero(ac) && !BN_is_zero(bc) && BN_cmp(ac, bc) != 0)
+ r = 1;
+ /* Returns 0 if the parameters matched */
}
-
+end:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(ctx_new);
-
+#endif
return r;
}
@@ -652,17 +718,17 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
EC_POINT *ret;
if (group == NULL) {
- ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (group->meth->point_init == NULL) {
- ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -679,7 +745,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
void EC_POINT_free(EC_POINT *point)
{
- if (!point)
+ if (point == NULL)
return;
if (point->meth->point_finish != 0)
@@ -689,7 +755,7 @@ void EC_POINT_free(EC_POINT *point)
void EC_POINT_clear_free(EC_POINT *point)
{
- if (!point)
+ if (point == NULL)
return;
if (point->meth->point_clear_finish != 0)
@@ -702,14 +768,14 @@ void EC_POINT_clear_free(EC_POINT *point)
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
{
if (dest->meth->point_copy == 0) {
- ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth
|| (dest->curve_name != src->curve_name
- && dest->curve_name != 0
- && src->curve_name != 0)) {
- ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+ && dest->curve_name != 0
+ && src->curve_name != 0)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == src)
@@ -736,42 +802,42 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
return t;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
{
return point->meth;
}
+#endif
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
{
if (group->meth->point_set_to_infinity == 0) {
- ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_to_infinity(group, point);
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
const BIGNUM *y, const BIGNUM *z,
BN_CTX *ctx)
{
- if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
- ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ if (group->meth->field_type != NID_X9_62_prime_field) {
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
- EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
- y, z, ctx);
+ return ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point,
+ x, y, z, ctx);
}
int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
@@ -779,44 +845,42 @@ int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
BIGNUM *y, BIGNUM *z,
BN_CTX *ctx)
{
- if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
- ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ if (group->meth->field_type != NID_X9_62_prime_field) {
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
- EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
- y, z, ctx);
+ return ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(group, point,
+ x, y, z, ctx);
}
+#endif
int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx)
{
if (group->meth->point_set_affine_coordinates == NULL) {
- ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
return 0;
if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
- ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_POINT_IS_NOT_ON_CURVE);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE);
return 0;
}
return 1;
}
-#if OPENSSL_API_COMPAT < 0x10200000L
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
const BIGNUM *y, BN_CTX *ctx)
@@ -839,22 +903,21 @@ int EC_POINT_get_affine_coordinates(const EC_GROUP *group,
BN_CTX *ctx)
{
if (group->meth->point_get_affine_coordinates == NULL) {
- ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
}
-#if OPENSSL_API_COMPAT < 0x10200000L
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
const EC_POINT *point, BIGNUM *x,
BIGNUM *y, BN_CTX *ctx)
@@ -876,12 +939,12 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx)
{
if (group->meth->add == 0) {
- ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)
|| !ec_point_is_compat(b, group)) {
- ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->add(group, r, a, b, ctx);
@@ -891,11 +954,11 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx)
{
if (group->meth->dbl == 0) {
- ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) {
- ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->dbl(group, r, a, ctx);
@@ -904,11 +967,11 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
{
if (group->meth->invert == 0) {
- ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(a, group)) {
- ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->invert(group, a, ctx);
@@ -917,12 +980,11 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
{
if (group->meth->is_at_infinity == 0) {
- ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_at_infinity(group, point);
@@ -939,11 +1001,11 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx)
{
if (group->meth->is_on_curve == 0) {
- ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_on_curve(group, point, ctx);
@@ -953,24 +1015,25 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx)
{
if (group->meth->point_cmp == 0) {
- ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) {
- ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
return group->meth->point_cmp(group, a, b, ctx);
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
{
if (group->meth->make_affine == 0) {
- ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->make_affine(group, point, ctx);
@@ -982,17 +1045,18 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
size_t i;
if (group->meth->points_make_affine == 0) {
- ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
for (i = 0; i < num; i++) {
if (!ec_point_is_compat(points[i], group)) {
- ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
return group->meth->points_make_affine(group, num, points, ctx);
}
+#endif
/*
* Functions for point multiplication. If group->meth->mul is 0, we use the
@@ -1000,16 +1064,19 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
* methods.
*/
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx)
{
int ret = 0;
size_t i = 0;
+#ifndef FIPS_MODULE
BN_CTX *new_ctx = NULL;
+#endif
if (!ec_point_is_compat(r, group)) {
- ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -1018,13 +1085,17 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
for (i = 0; i < num; i++) {
if (!ec_point_is_compat(points[i], group)) {
- ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) {
- ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR);
+#ifndef FIPS_MODULE
+ if (ctx == NULL)
+ ctx = new_ctx = BN_CTX_secure_new();
+#endif
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1032,33 +1103,61 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);
else
/* use default */
- ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ ret = ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
+#endif
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
{
- /* just a convenient interface to EC_POINTs_mul() */
+ int ret = 0;
+ size_t num;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
+
+ if (!ec_point_is_compat(r, group)
+ || (point != NULL && !ec_point_is_compat(point, group))) {
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
- const EC_POINT *points[1];
- const BIGNUM *scalars[1];
+ if (g_scalar == NULL && p_scalar == NULL)
+ return EC_POINT_set_to_infinity(group, r);
- points[0] = point;
- scalars[0] = p_scalar;
+#ifndef FIPS_MODULE
+ if (ctx == NULL)
+ ctx = new_ctx = BN_CTX_secure_new();
+#endif
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ num = (point != NULL && p_scalar != NULL) ? 1 : 0;
+ if (group->meth->mul != NULL)
+ ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
+ else
+ /* use default */
+ ret = ossl_ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
- return EC_POINTs_mul(group, r, g_scalar,
- (point != NULL
- && p_scalar != NULL), points, scalars, ctx);
+#ifndef FIPS_MODULE
+ BN_CTX_free(new_ctx);
+#endif
+ return ret;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
if (group->meth->mul == 0)
/* use default */
- return ec_wNAF_precompute_mult(group, ctx);
+ return ossl_ec_wNAF_precompute_mult(group, ctx);
if (group->meth->precompute_mult != 0)
return group->meth->precompute_mult(group, ctx);
@@ -1070,7 +1169,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
{
if (group->meth->mul == 0)
/* use default */
- return ec_wNAF_have_precompute_mult(group);
+ return ossl_ec_wNAF_have_precompute_mult(group);
if (group->meth->have_precompute_mult != 0)
return group->meth->have_precompute_mult(group);
@@ -1078,6 +1177,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
return 0; /* cannot tell whether precomputation has
* been performed */
}
+#endif
/*
* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
@@ -1085,7 +1185,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
*/
static int ec_precompute_mont_data(EC_GROUP *group)
{
- BN_CTX *ctx = BN_CTX_new();
+ BN_CTX *ctx = BN_CTX_new_ex(group->libctx);
int ret = 0;
BN_MONT_CTX_free(group->mont_data);
@@ -1112,6 +1212,7 @@ static int ec_precompute_mont_data(EC_GROUP *group)
return ret;
}
+#ifndef FIPS_MODULE
int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
{
return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
@@ -1121,8 +1222,9 @@ void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
{
return CRYPTO_get_ex_data(&key->ex_data, idx);
}
+#endif
-int ec_group_simple_order_bits(const EC_GROUP *group)
+int ossl_ec_group_simple_order_bits(const EC_GROUP *group)
{
if (group->order == NULL)
return 0;
@@ -1133,13 +1235,19 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
const BIGNUM *x, BN_CTX *ctx)
{
BIGNUM *e = NULL;
- BN_CTX *new_ctx = NULL;
int ret = 0;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
if (group->mont_data == NULL)
return 0;
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
+#ifndef FIPS_MODULE
+ if (ctx == NULL)
+ ctx = new_ctx = BN_CTX_secure_new();
+#endif
+ if (ctx == NULL)
return 0;
BN_CTX_start(ctx);
@@ -1155,17 +1263,19 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
if (!BN_sub(e, group->order, e))
goto err;
/*-
- * Exponent e is public.
- * No need for scatter-gather or BN_FLG_CONSTTIME.
+ * Although the exponent is public we want the result to be
+ * fixed top.
*/
- if (!BN_mod_exp_mont(r, x, e, group->order, ctx, group->mont_data))
+ if (!bn_mod_exp_mont_fixed_top(r, x, e, group->order, ctx, group->mont_data))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -1182,8 +1292,8 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
* EC_METHODs must implement their own field_inverse_mod_ord for
* other functionality.
*/
-int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
- const BIGNUM *x, BN_CTX *ctx)
+int ossl_ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
+ const BIGNUM *x, BN_CTX *ctx)
{
if (group->meth->field_inverse_mod_ord != NULL)
return group->meth->field_inverse_mod_ord(group, res, x, ctx);
@@ -1201,10 +1311,451 @@ int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
* This wrapper returns 1 in case the underlying EC_METHOD does not
* support coordinate blinding.
*/
-int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
+int ossl_ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+ BN_CTX *ctx)
{
if (group->meth->blind_coordinates == NULL)
return 1; /* ignore if not implemented */
return group->meth->blind_coordinates(group, p, ctx);
}
+
+int EC_GROUP_get_basis_type(const EC_GROUP *group)
+{
+ int i;
+
+ if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field)
+ /* everything else is currently not supported */
+ return 0;
+
+ /* Find the last non-zero element of group->poly[] */
+ for (i = 0;
+ i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
+ i++)
+ continue;
+
+ if (i == 4)
+ return NID_X9_62_ppBasis;
+ else if (i == 2)
+ return NID_X9_62_tpBasis;
+ else
+ /* everything else is currently not supported */
+ return 0;
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
+{
+ if (group == NULL)
+ return 0;
+
+ if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
+ || !((group->poly[0] != 0) && (group->poly[1] != 0)
+ && (group->poly[2] == 0))) {
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (k)
+ *k = group->poly[1];
+
+ return 1;
+}
+
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
+ unsigned int *k2, unsigned int *k3)
+{
+ if (group == NULL)
+ return 0;
+
+ if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
+ || !((group->poly[0] != 0) && (group->poly[1] != 0)
+ && (group->poly[2] != 0) && (group->poly[3] != 0)
+ && (group->poly[4] == 0))) {
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (k1)
+ *k1 = group->poly[3];
+ if (k2)
+ *k2 = group->poly[2];
+ if (k3)
+ *k3 = group->poly[1];
+
+ return 1;
+}
+#endif
+
+#ifndef FIPS_MODULE
+/*
+ * Check if the explicit parameters group matches any built-in curves.
+ *
+ * We create a copy of the group just built, so that we can remove optional
+ * fields for the lookup: we do this to avoid the possibility that one of
+ * the optional parameters is used to force the library into using a less
+ * performant and less secure EC_METHOD instead of the specialized one.
+ * In any case, `seed` is not really used in any computation, while a
+ * cofactor different from the one in the built-in table is just
+ * mathematically wrong anyway and should not be used.
+ */
+static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group,
+ OSSL_LIB_CTX *libctx,
+ const char *propq,
+ BN_CTX *ctx)
+{
+ EC_GROUP *ret_group = NULL, *dup = NULL;
+ int curve_name_nid;
+
+ const EC_POINT *point = EC_GROUP_get0_generator(group);
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+ int no_seed = (EC_GROUP_get0_seed(group) == NULL);
+
+ if ((dup = EC_GROUP_dup(group)) == NULL
+ || EC_GROUP_set_seed(dup, NULL, 0) != 1
+ || !EC_GROUP_set_generator(dup, point, order, NULL))
+ goto err;
+ if ((curve_name_nid = ossl_ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
+ /*
+ * The input explicit parameters successfully matched one of the
+ * built-in curves: often for built-in curves we have specialized
+ * methods with better performance and hardening.
+ *
+ * In this case we replace the `EC_GROUP` created through explicit
+ * parameters with one created from a named group.
+ */
+
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ /*
+ * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
+ * the same curve, we prefer the SECP nid when matching explicit
+ * parameters as that is associated with a specialized EC_METHOD.
+ */
+ if (curve_name_nid == NID_wap_wsg_idm_ecid_wtls12)
+ curve_name_nid = NID_secp224r1;
+# endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
+
+ ret_group = EC_GROUP_new_by_curve_name_ex(libctx, propq, curve_name_nid);
+ if (ret_group == NULL)
+ goto err;
+
+ /*
+ * Set the flag so that EC_GROUPs created from explicit parameters are
+ * serialized using explicit parameters by default.
+ */
+ EC_GROUP_set_asn1_flag(ret_group, OPENSSL_EC_EXPLICIT_CURVE);
+
+ /*
+ * If the input params do not contain the optional seed field we make
+ * sure it is not added to the returned group.
+ *
+ * The seed field is not really used inside libcrypto anyway, and
+ * adding it to parsed explicit parameter keys would alter their DER
+ * encoding output (because of the extra field) which could impact
+ * applications fingerprinting keys by their DER encoding.
+ */
+ if (no_seed) {
+ if (EC_GROUP_set_seed(ret_group, NULL, 0) != 1)
+ goto err;
+ }
+ } else {
+ ret_group = (EC_GROUP *)group;
+ }
+ EC_GROUP_free(dup);
+ return ret_group;
+err:
+ EC_GROUP_free(dup);
+ EC_GROUP_free(ret_group);
+ return NULL;
+}
+#endif /* FIPS_MODULE */
+
+static EC_GROUP *group_new_from_name(const OSSL_PARAM *p,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ int ok = 0, nid;
+ const char *curve_name = NULL;
+
+ switch (p->data_type) {
+ case OSSL_PARAM_UTF8_STRING:
+ /* The OSSL_PARAM functions have no support for this */
+ curve_name = p->data;
+ ok = (curve_name != NULL);
+ break;
+ case OSSL_PARAM_UTF8_PTR:
+ ok = OSSL_PARAM_get_utf8_ptr(p, &curve_name);
+ break;
+ }
+
+ if (ok) {
+ nid = ossl_ec_curve_name2nid(curve_name);
+ if (nid == NID_undef) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE);
+ return NULL;
+ } else {
+ return EC_GROUP_new_by_curve_name_ex(libctx, propq, nid);
+ }
+ }
+ return NULL;
+}
+
+/* These parameters can be set directly into an EC_GROUP */
+int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[])
+{
+ int encoding_flag = -1, format = -1;
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT);
+ if (p != NULL) {
+ if (!ossl_ec_pt_format_param2id(p, &format)) {
+ ECerr(0, EC_R_INVALID_FORM);
+ return 0;
+ }
+ EC_GROUP_set_point_conversion_form(group, format);
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING);
+ if (p != NULL) {
+ if (!ossl_ec_encoding_param2id(p, &encoding_flag)) {
+ ECerr(0, EC_R_INVALID_FORM);
+ return 0;
+ }
+ EC_GROUP_set_asn1_flag(group, encoding_flag);
+ }
+ /* Optional seed */
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED);
+ if (p != NULL) {
+ /* The seed is allowed to be NULL */
+ if (p->data_type != OSSL_PARAM_OCTET_STRING
+ || !EC_GROUP_set_seed(group, p->data, p->data_size)) {
+ ECerr(0, EC_R_INVALID_SEED);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ const OSSL_PARAM *ptmp;
+ EC_GROUP *group = NULL;
+
+#ifndef FIPS_MODULE
+ const OSSL_PARAM *pa, *pb;
+ int ok = 0;
+ EC_GROUP *named_group = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL;
+ EC_POINT *point = NULL;
+ int field_bits = 0;
+ int is_prime_field = 1;
+ BN_CTX *bnctx = NULL;
+ const unsigned char *buf = NULL;
+ int encoding_flag = -1;
+#endif
+
+ /* This is the simple named group case */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
+ if (ptmp != NULL) {
+ int decoded = 0;
+
+ if ((group = group_new_from_name(ptmp, libctx, propq)) == NULL)
+ return NULL;
+ if (!ossl_ec_group_set_params(group, params)) {
+ EC_GROUP_free(group);
+ return NULL;
+ }
+
+ ptmp = OSSL_PARAM_locate_const(params,
+ OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS);
+ if (ptmp != NULL && !OSSL_PARAM_get_int(ptmp, &decoded)) {
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
+ EC_GROUP_free(group);
+ return NULL;
+ }
+ group->decoded_from_explicit_params = decoded > 0;
+ return group;
+ }
+#ifdef FIPS_MODULE
+ ERR_raise(ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED);
+ return NULL;
+#else
+ /* If it gets here then we are trying explicit parameters */
+ bnctx = BN_CTX_new_ex(libctx);
+ if (bnctx == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ BN_CTX_start(bnctx);
+
+ p = BN_CTX_get(bnctx);
+ a = BN_CTX_get(bnctx);
+ b = BN_CTX_get(bnctx);
+ order = BN_CTX_get(bnctx);
+ if (order == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE);
+ if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
+ goto err;
+ }
+ if (OPENSSL_strcasecmp(ptmp->data, SN_X9_62_prime_field) == 0) {
+ is_prime_field = 1;
+ } else if (OPENSSL_strcasecmp(ptmp->data,
+ SN_X9_62_characteristic_two_field) == 0) {
+ is_prime_field = 0;
+ } else {
+ /* Invalid field */
+ ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD);
+ goto err;
+ }
+
+ pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A);
+ if (!OSSL_PARAM_get_BN(pa, &a)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_A);
+ goto err;
+ }
+ pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B);
+ if (!OSSL_PARAM_get_BN(pb, &b)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_B);
+ goto err;
+ }
+
+ /* extract the prime number or irreducible polynomial */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P);
+ if (!OSSL_PARAM_get_BN(ptmp, &p)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_P);
+ goto err;
+ }
+
+ if (is_prime_field) {
+ if (BN_is_negative(p) || BN_is_zero(p)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_P);
+ goto err;
+ }
+ field_bits = BN_num_bits(p);
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+ ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+
+ /* create the EC_GROUP structure */
+ group = EC_GROUP_new_curve_GFp(p, a, b, bnctx);
+ } else {
+# ifdef OPENSSL_NO_EC2M
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+# else
+ /* create the EC_GROUP structure */
+ group = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+ if (group != NULL) {
+ field_bits = EC_GROUP_get_degree(group);
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+ ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+ }
+# endif /* OPENSSL_NO_EC2M */
+ }
+
+ if (group == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ /* Optional seed */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED);
+ if (ptmp != NULL) {
+ if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED);
+ goto err;
+ }
+ if (!EC_GROUP_set_seed(group, ptmp->data, ptmp->data_size))
+ goto err;
+ }
+
+ /* generator base point */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR);
+ if (ptmp == NULL
+ || ptmp->data_type != OSSL_PARAM_OCTET_STRING) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR);
+ goto err;
+ }
+ buf = (const unsigned char *)(ptmp->data);
+ if ((point = EC_POINT_new(group)) == NULL)
+ goto err;
+ EC_GROUP_set_point_conversion_form(group,
+ (point_conversion_form_t)buf[0] & ~0x01);
+ if (!EC_POINT_oct2point(group, point, buf, ptmp->data_size, bnctx)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR);
+ goto err;
+ }
+
+ /* order */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER);
+ if (!OSSL_PARAM_get_BN(ptmp, &order)
+ || (BN_is_negative(order) || BN_is_zero(order))
+ || (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+
+ /* Optional cofactor */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR);
+ if (ptmp != NULL) {
+ cofactor = BN_CTX_get(bnctx);
+ if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_COFACTOR);
+ goto err;
+ }
+ }
+
+ /* set the generator, order and cofactor (if present) */
+ if (!EC_GROUP_set_generator(group, point, order, cofactor)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR);
+ goto err;
+ }
+
+ named_group = ec_group_explicit_to_named(group, libctx, propq, bnctx);
+ if (named_group == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION);
+ goto err;
+ }
+ if (named_group == group) {
+ /*
+ * If we did not find a named group then the encoding should be explicit
+ * if it was specified
+ */
+ ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING);
+ if (ptmp != NULL
+ && !ossl_ec_encoding_param2id(ptmp, &encoding_flag)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (encoding_flag == OPENSSL_EC_NAMED_CURVE) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
+ } else {
+ EC_GROUP_free(group);
+ group = named_group;
+ }
+ /* We've imported the group from explicit parameters, set it so. */
+ group->decoded_from_explicit_params = 1;
+ ok = 1;
+ err:
+ if (!ok) {
+ EC_GROUP_free(group);
+ group = NULL;
+ }
+ EC_POINT_free(point);
+ BN_CTX_end(bnctx);
+ BN_CTX_free(bnctx);
+
+ return group;
+#endif /* FIPS_MODULE */
+}
diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h
index 64725a9c92f4..f34e06aea89a 100644
--- a/crypto/ec/ec_local.h
+++ b/crypto/ec/ec_local.h
@@ -1,8 +1,8 @@
/*
- * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -31,6 +31,10 @@
/* Curve does not support signing operations */
#define EC_FLAGS_NO_SIGN 0x4
+#ifdef OPENSSL_NO_DEPRECATED_3_0
+typedef struct ec_method_st EC_METHOD;
+#endif
+
/*
* Structure details are not part of the exported interface, so all this may
* change in future versions.
@@ -76,14 +80,6 @@ struct ec_method_st {
* EC_POINT_set_compressed_coordinates:
*/
int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
- int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
- EC_POINT *, const BIGNUM *x,
- const BIGNUM *y,
- const BIGNUM *z, BN_CTX *);
- int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BIGNUM *z,
- BN_CTX *);
int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *);
@@ -179,6 +175,14 @@ struct ec_method_st {
/* custom ECDH operation */
int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
const EC_POINT *pub_key, const EC_KEY *ecdh);
+ /* custom ECDSA */
+ int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinvp,
+ BIGNUM **rp);
+ ECDSA_SIG *(*ecdsa_sign_sig)(const unsigned char *dgst, int dgstlen,
+ const BIGNUM *kinv, const BIGNUM *r,
+ EC_KEY *eckey);
+ int (*ecdsa_verify_sig)(const unsigned char *dgst, int dgstlen,
+ const ECDSA_SIG *sig, EC_KEY *eckey);
/* Inverse modulo order */
int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r,
const BIGNUM *x, BN_CTX *);
@@ -270,6 +274,9 @@ struct ec_group_st {
NISTZ256_PRE_COMP *nistz256;
EC_PRE_COMP *ec;
} pre_comp;
+
+ OSSL_LIB_CTX *libctx;
+ char *propq;
};
#define SETPRECOMP(g, type, pre) \
@@ -288,8 +295,15 @@ struct ec_key_st {
point_conversion_form_t conv_form;
CRYPTO_REF_COUNT references;
int flags;
+#ifndef FIPS_MODULE
CRYPTO_EX_DATA ex_data;
+#endif
CRYPTO_RWLOCK *lock;
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+
+ /* Provider data */
+ size_t dirty_cnt; /* If any key material changes, increment this */
};
struct ec_point_st {
@@ -311,13 +325,10 @@ struct ec_point_st {
static ossl_inline int ec_point_is_compat(const EC_POINT *point,
const EC_GROUP *group)
{
- if (group->meth != point->meth
- || (group->curve_name != 0
- && point->curve_name != 0
- && group->curve_name != point->curve_name))
- return 0;
-
- return 1;
+ return group->meth == point->meth
+ && (group->curve_name == 0
+ || point->curve_name == 0
+ || group->curve_name == point->curve_name);
}
NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
@@ -338,249 +349,264 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *);
* method functions in ec_mult.c (ec_lib.c uses these as defaults if
* group->method->mul is 0)
*/
-int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
-int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *);
+int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
+int ossl_ec_wNAF_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_smpl.c */
-int ec_GFp_simple_group_init(EC_GROUP *);
-void ec_GFp_simple_group_finish(EC_GROUP *);
-void ec_GFp_simple_group_clear_finish(EC_GROUP *);
-int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
-int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
- BIGNUM *b, BN_CTX *);
-int ec_GFp_simple_group_get_degree(const EC_GROUP *);
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
-int ec_GFp_simple_point_init(EC_POINT *);
-void ec_GFp_simple_point_finish(EC_POINT *);
-void ec_GFp_simple_point_clear_finish(EC_POINT *);
-int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
-int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
-int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
- EC_POINT *, const BIGNUM *x,
- const BIGNUM *y,
- const BIGNUM *z, BN_CTX *);
-int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BIGNUM *z,
+int ossl_ec_GFp_simple_group_init(EC_GROUP *);
+void ossl_ec_GFp_simple_group_finish(EC_GROUP *);
+void ossl_ec_GFp_simple_group_clear_finish(EC_GROUP *);
+int ossl_ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ossl_ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *);
+int ossl_ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *);
+int ossl_ec_GFp_simple_group_get_degree(const EC_GROUP *);
+int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ossl_ec_GFp_simple_point_init(EC_POINT *);
+void ossl_ec_GFp_simple_point_finish(EC_POINT *);
+void ossl_ec_GFp_simple_point_clear_finish(EC_POINT *);
+int ossl_ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ossl_ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
+ EC_POINT *,
+ const BIGNUM *x,
+ const BIGNUM *y,
+ const BIGNUM *z,
+ BN_CTX *);
+int ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
+ const EC_POINT *,
+ BIGNUM *x,
+ BIGNUM *y, BIGNUM *z,
+ BN_CTX *);
+int ossl_ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *);
+int ossl_ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BN_CTX *);
+int ossl_ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, int y_bit,
BN_CTX *);
-int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x,
- const BIGNUM *y, BN_CTX *);
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BN_CTX *);
-int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, int y_bit,
- BN_CTX *);
-size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
- point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *);
-int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
- const unsigned char *buf, size_t len, BN_CTX *);
-int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *);
-int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- BN_CTX *);
-int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
- BN_CTX *);
-int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
- EC_POINT *[], BN_CTX *);
-int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
- BN_CTX *ctx);
-int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx);
-int ec_GFp_simple_ladder_step(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx);
-int ec_GFp_simple_ladder_post(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx);
+size_t ossl_ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *);
+int ossl_ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
+ const unsigned char *buf, size_t len, BN_CTX *);
+int ossl_ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ossl_ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *);
+int ossl_ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ossl_ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ossl_ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ossl_ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ossl_ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ossl_ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
+ EC_POINT *[], BN_CTX *);
+int ossl_ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ossl_ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+ BN_CTX *ctx);
+int ossl_ec_GFp_simple_ladder_pre(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx);
+int ossl_ec_GFp_simple_ladder_step(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx);
+int ossl_ec_GFp_simple_ladder_post(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx);
/* method functions in ecp_mont.c */
-int ec_GFp_mont_group_init(EC_GROUP *);
-int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-void ec_GFp_mont_group_finish(EC_GROUP *);
-void ec_GFp_mont_group_clear_finish(EC_GROUP *);
-int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
-int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+int ossl_ec_GFp_mont_group_init(EC_GROUP *);
+int ossl_ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+void ossl_ec_GFp_mont_group_finish(EC_GROUP *);
+void ossl_ec_GFp_mont_group_clear_finish(EC_GROUP *);
+int ossl_ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
+int ossl_ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ossl_ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
/* method functions in ecp_nist.c */
-int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
-int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
+int ossl_ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
+int ossl_ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ossl_ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ossl_ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
/* method functions in ec2_smpl.c */
-int ec_GF2m_simple_group_init(EC_GROUP *);
-void ec_GF2m_simple_group_finish(EC_GROUP *);
-void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
-int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
-int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *);
-int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
- BIGNUM *b, BN_CTX *);
-int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
-int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
-int ec_GF2m_simple_point_init(EC_POINT *);
-void ec_GF2m_simple_point_finish(EC_POINT *);
-void ec_GF2m_simple_point_clear_finish(EC_POINT *);
-int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
-int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
-int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x,
- const BIGNUM *y, BN_CTX *);
-int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BN_CTX *);
-int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, int y_bit,
- BN_CTX *);
-size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
- point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *);
-int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
- const unsigned char *buf, size_t len, BN_CTX *);
-int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *);
-int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- BN_CTX *);
-int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
- BN_CTX *);
-int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
- EC_POINT *[], BN_CTX *);
-int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
-int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- BN_CTX *);
-int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
+int ossl_ec_GF2m_simple_group_init(EC_GROUP *);
+void ossl_ec_GF2m_simple_group_finish(EC_GROUP *);
+void ossl_ec_GF2m_simple_group_clear_finish(EC_GROUP *);
+int ossl_ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ossl_ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *);
+int ossl_ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *);
+int ossl_ec_GF2m_simple_group_get_degree(const EC_GROUP *);
+int ossl_ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ossl_ec_GF2m_simple_point_init(EC_POINT *);
+void ossl_ec_GF2m_simple_point_finish(EC_POINT *);
+void ossl_ec_GF2m_simple_point_clear_finish(EC_POINT *);
+int ossl_ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ossl_ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ossl_ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *,
+ EC_POINT *,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *);
+int ossl_ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BN_CTX *);
+int ossl_ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, int y_bit,
+ BN_CTX *);
+size_t ossl_ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *);
+int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
+ const unsigned char *buf, size_t len, BN_CTX *);
+int ossl_ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ossl_ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *);
+int ossl_ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ossl_ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ossl_ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ossl_ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ossl_ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ossl_ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
+ EC_POINT *[], BN_CTX *);
+int ossl_ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ossl_ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ossl_ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# ifdef B_ENDIAN
+# error "Can not enable ec_nistp_64_gcc_128 on big-endian systems"
+# endif
+
/* method functions in ecp_nistp224.c */
-int ec_GFp_nistp224_group_init(EC_GROUP *group);
-int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *n,
- BN_CTX *);
-int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx);
-int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
-int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx);
-int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
+int ossl_ec_GFp_nistp224_group_init(EC_GROUP *group);
+int ossl_ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ossl_ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ossl_ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ossl_ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ossl_ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ossl_ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_nistp256.c */
-int ec_GFp_nistp256_group_init(EC_GROUP *group);
-int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *n,
- BN_CTX *);
-int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx);
-int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
-int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx);
-int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+int ossl_ec_GFp_nistp256_group_init(EC_GROUP *group);
+int ossl_ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ossl_ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ossl_ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_nistp521.c */
-int ec_GFp_nistp521_group_init(EC_GROUP *group);
-int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *n,
- BN_CTX *);
-int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx);
-int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
-int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx);
-int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
+int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group);
+int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ossl_ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ossl_ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ossl_ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ossl_ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ossl_ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
/* utility functions in ecp_nistputil.c */
-void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
- size_t felem_size,
- void *tmp_felems,
- void (*felem_one) (void *out),
- int (*felem_is_zero) (const void
- *in),
- void (*felem_assign) (void *out,
- const void
- *in),
- void (*felem_square) (void *out,
- const void
- *in),
- void (*felem_mul) (void *out,
- const void
- *in1,
- const void
- *in2),
- void (*felem_inv) (void *out,
- const void
- *in),
- void (*felem_contract) (void
- *out,
- const
- void
- *in));
-void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
- unsigned char *digit, unsigned char in);
+void ossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+ size_t felem_size,
+ void *tmp_felems,
+ void (*felem_one) (void *out),
+ int (*felem_is_zero)
+ (const void *in),
+ void (*felem_assign)
+ (void *out, const void *in),
+ void (*felem_square)
+ (void *out, const void *in),
+ void (*felem_mul)
+ (void *out,
+ const void *in1,
+ const void *in2),
+ void (*felem_inv)
+ (void *out, const void *in),
+ void (*felem_contract)
+ (void *out, const void *in));
+void ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+ unsigned char *digit,
+ unsigned char in);
#endif
-int ec_group_simple_order_bits(const EC_GROUP *group);
+int ossl_ec_group_simple_order_bits(const EC_GROUP *group);
+
+/**
+ * Creates a new EC_GROUP object
+ * \param libctx The associated library context or NULL for the default
+ * library context
+ * \param propq Any property query string
+ * \param meth EC_METHOD to use
+ * \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
+ const EC_METHOD *meth);
#ifdef ECP_NISTZ256_ASM
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
@@ -589,15 +615,21 @@ int ec_group_simple_order_bits(const EC_GROUP *group);
*/
const EC_METHOD *EC_GFp_nistz256_method(void);
#endif
+#ifdef S390X_EC_ASM
+const EC_METHOD *EC_GFp_s390x_nistp256_method(void);
+const EC_METHOD *EC_GFp_s390x_nistp384_method(void);
+const EC_METHOD *EC_GFp_s390x_nistp521_method(void);
+#endif
-size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
- unsigned char *buf, size_t len);
-int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len);
-int ec_key_simple_generate_key(EC_KEY *eckey);
-int ec_key_simple_generate_public_key(EC_KEY *eckey);
-int ec_key_simple_check_key(const EC_KEY *eckey);
+size_t ossl_ec_key_simple_priv2oct(const EC_KEY *eckey,
+ unsigned char *buf, size_t len);
+int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf,
+ size_t len);
+int ossl_ec_key_simple_generate_key(EC_KEY *eckey);
+int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey);
+int ossl_ec_key_simple_check_key(const EC_KEY *eckey);
-int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
+int ossl_ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
/* EC_METHOD definitions */
@@ -630,11 +662,14 @@ struct ec_key_method_st {
#define EC_KEY_METHOD_DYNAMIC 1
+EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq,
+ ENGINE *engine);
+
int ossl_ec_key_gen(EC_KEY *eckey);
int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
const EC_POINT *pub_key, const EC_KEY *ecdh);
-int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
- const EC_POINT *pub_key, const EC_KEY *ecdh);
+int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
+ const EC_POINT *pub_key, const EC_KEY *ecdh);
struct ECDSA_SIG_st {
BIGNUM *r;
@@ -653,18 +688,14 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey);
+int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp);
+ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey);
+int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey);
-int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
- const uint8_t public_key[32], const uint8_t private_key[32]);
-int ED25519_verify(const uint8_t *message, size_t message_len,
- const uint8_t signature[64], const uint8_t public_key[32]);
-void ED25519_public_from_private(uint8_t out_public_key[32],
- const uint8_t private_key[32]);
-
-int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
- const uint8_t peer_public_value[32]);
-void X25519_public_from_private(uint8_t out_public_value[32],
- const uint8_t private_key[32]);
/*-
* This functions computes a single point multiplication over the EC group,
@@ -695,11 +726,12 @@ void X25519_public_from_private(uint8_t out_public_value[32],
*
* Returns 1 on success, 0 otherwise.
*/
-int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, const EC_POINT *point,
- BN_CTX *ctx);
+int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, const EC_POINT *point,
+ BN_CTX *ctx);
-int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
+int ossl_ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+ BN_CTX *ctx);
static ossl_inline int ec_point_ladder_pre(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 9a1e3974ed9e..c6ec2964b7c4 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include <openssl/err.h>
@@ -51,7 +57,7 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
@@ -62,7 +68,7 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
@@ -136,9 +142,9 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
*
* Returns 1 on success, 0 otherwise.
*/
-int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, const EC_POINT *point,
- BN_CTX *ctx)
+int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, const EC_POINT *point,
+ BN_CTX *ctx)
{
int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
EC_POINT *p = NULL;
@@ -153,11 +159,11 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
return EC_POINT_set_to_infinity(group, r);
if (BN_is_zero(group->order)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER);
return 0;
}
if (BN_is_zero(group->cofactor)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR);
return 0;
}
@@ -165,18 +171,18 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
if (((p = EC_POINT_new(group)) == NULL)
|| ((s = EC_POINT_new(group)) == NULL)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (point == NULL) {
if (!EC_POINT_copy(p, group->generator)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_POINT_copy(p, point)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -189,12 +195,12 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
lambda = BN_CTX_get(ctx);
k = BN_CTX_get(ctx);
if (k == NULL) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -208,12 +214,12 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
group_top = bn_get_top(cardinality);
if ((bn_wexpand(k, group_top + 2) == NULL)
|| (bn_wexpand(lambda, group_top + 2) == NULL)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (!BN_copy(k, scalar)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -225,18 +231,18 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(k, k, cardinality, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
}
if (!BN_add(lambda, k, cardinality)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
BN_set_flags(lambda, BN_FLG_CONSTTIME);
if (!BN_add(k, lambda, cardinality)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/*
@@ -256,19 +262,20 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|| (bn_wexpand(p->X, group_top) == NULL)
|| (bn_wexpand(p->Y, group_top) == NULL)
|| (bn_wexpand(p->Z, group_top) == NULL)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* ensure input point is in affine coords for ladder step efficiency */
- if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
+ if (!p->Z_is_one && (group->meth->make_affine == NULL
+ || !group->meth->make_affine(group, p, ctx))) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
/* Initialize the Montgomery ladder */
if (!ec_point_ladder_pre(group, r, s, p, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE);
goto err;
}
@@ -348,7 +355,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
/* Perform a single step of the Montgomery ladder */
if (!ec_point_ladder_step(group, r, s, p, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE);
goto err;
}
/*
@@ -363,7 +370,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
/* Finalize ladder (and recover full point coordinates) */
if (!ec_point_ladder_post(group, r, s, p, ctx)) {
- ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_LADDER_POST_FAILURE);
goto err;
}
@@ -380,7 +387,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
#undef EC_POINT_BN_set_flags
/*
- * TODO: table should be optimised for the wNAF-based implementation,
+ * Table could be optimised for the wNAF-based implementation,
* sometimes smaller windows will give better performance (thus the
* boundaries should be increased)
*/
@@ -400,9 +407,9 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
* scalar*generator
* in the addition if scalar != NULL
*/
-int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *ctx)
+int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
{
const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
@@ -443,7 +450,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* is why we ignore if BN_FLG_CONSTTIME is actually set and we
* always call the ladder version.
*/
- return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
+ return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
}
if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) {
/*-
@@ -453,14 +460,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is
* actually set and we always call the ladder version.
*/
- return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
+ return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0],
+ ctx);
}
}
if (scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
@@ -488,7 +496,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* check that pre_comp looks sane */
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
} else {
@@ -513,7 +521,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
wNAF[0] = NULL; /* preliminary pivot */
if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -543,7 +551,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
if (pre_comp == NULL) {
if (num_scalar != 1) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
/* we have already generated a wNAF for 'scalar' */
@@ -552,7 +560,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t tmp_len = 0;
if (num_scalar != 0) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -595,7 +603,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
*/
numblocks = (tmp_len + blocksize - 1) / blocksize;
if (numblocks > pre_comp->numblocks) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -610,7 +618,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
if (i < totalnum - 1) {
wNAF_len[i] = blocksize;
if (tmp_len < blocksize) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -625,7 +633,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
wNAF[i + 1] = NULL;
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
if (wNAF[i] == NULL) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -634,7 +642,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
max_len = wNAF_len[i];
if (*tmp_points == NULL) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -654,7 +662,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
*/
val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));
if (val == NULL) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
val[num_val] = NULL; /* pivot element */
@@ -671,7 +679,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
if (!(v == val + num_val)) {
- ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -705,7 +713,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
- if (!EC_POINTs_make_affine(group, num_val, val, ctx))
+ if (group->meth->points_make_affine == NULL
+ || !group->meth->points_make_affine(group, num_val, val, ctx))
goto err;
r_is_at_infinity = 1;
@@ -745,12 +754,12 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* Apply coordinate blinding for EC_POINT.
*
* The underlying EC_METHOD can optionally implement this function:
- * ec_point_blind_coordinates() returns 0 in case of errors or 1 on
+ * ossl_ec_point_blind_coordinates() returns 0 in case of errors or 1 on
* success or if coordinate blinding is not implemented for this
* group.
*/
- if (!ec_point_blind_coordinates(group, r, ctx)) {
- ECerr(EC_F_EC_WNAF_MUL, EC_R_POINT_COORDINATES_BLIND_FAILURE);
+ if (!ossl_ec_point_blind_coordinates(group, r, ctx)) {
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE);
goto err;
}
@@ -799,9 +808,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
/*-
- * ec_wNAF_precompute_mult()
+ * ossl_ec_wNAF_precompute_mult()
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
- * for use with wNAF splitting as implemented in ec_wNAF_mul().
+ * for use with wNAF splitting as implemented in ossl_ec_wNAF_mul().
*
* 'pre_comp->points' is an array of multiples of the generator
* of the following form:
@@ -818,16 +827,19 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
* points[2^(w-1)*numblocks] = NULL
*/
-int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
const EC_POINT *generator;
EC_POINT *tmp_point = NULL, *base = NULL, **var;
- BN_CTX *new_ctx = NULL;
const BIGNUM *order;
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
EC_POINT **points = NULL;
EC_PRE_COMP *pre_comp;
int ret = 0;
+ int used_ctx = 0;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
/* if there is an old EC_PRE_COMP object, throw it away */
EC_pre_comp_free(group);
@@ -836,23 +848,25 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
- if (ctx == NULL) {
+#ifndef FIPS_MODULE
+ if (ctx == NULL)
ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- goto err;
- }
+#endif
+ if (ctx == NULL)
+ goto err;
BN_CTX_start(ctx);
+ used_ctx = 1;
order = EC_GROUP_get0_order(group);
if (order == NULL)
goto err;
if (BN_is_zero(order)) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER);
goto err;
}
@@ -880,7 +894,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
points = OPENSSL_malloc(sizeof(*points) * (num + 1));
if (points == NULL) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -888,14 +902,14 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
var[num] = NULL; /* pivot */
for (i = 0; i < num; i++) {
if ((var[i] = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if ((tmp_point = EC_POINT_new(group)) == NULL
|| (base = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -927,7 +941,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
size_t k;
if (blocksize <= 2) {
- ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -940,7 +954,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
}
}
- if (!EC_POINTs_make_affine(group, num, points, ctx))
+ if (group->meth->points_make_affine == NULL
+ || !group->meth->points_make_affine(group, num, points, ctx))
goto err;
pre_comp->group = group;
@@ -955,8 +970,11 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
ret = 1;
err:
- BN_CTX_end(ctx);
+ if (used_ctx)
+ BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
EC_ec_pre_comp_free(pre_comp);
if (points) {
EC_POINT **p;
@@ -970,7 +988,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
return ret;
}
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
+int ossl_ec_wNAF_have_precompute_mult(const EC_GROUP *group)
{
return HAVEPRECOMP(group, ec);
}
diff --git a/crypto/ec/ec_oct.c b/crypto/ec/ec_oct.c
index 7ddc86b047ca..2b77e9738883 100644
--- a/crypto/ec/ec_oct.c
+++ b/crypto/ec/ec_oct.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include <openssl/err.h>
@@ -20,36 +26,33 @@ int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
{
if (group->meth->point_set_compressed_coordinates == NULL
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
- EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
- return ec_GFp_simple_set_compressed_coordinates(group, point, x,
- y_bit, ctx);
+ return ossl_ec_GFp_simple_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
else
#ifdef OPENSSL_NO_EC2M
{
- ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
- EC_R_GF2M_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
- return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
- y_bit, ctx);
+ return ossl_ec_GF2m_simple_set_compressed_coordinates(group, point,
+ x, y_bit, ctx);
#endif
}
return group->meth->point_set_compressed_coordinates(group, point, x,
y_bit, ctx);
}
-#if OPENSSL_API_COMPAT < 0x10200000L
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx)
@@ -71,27 +74,32 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, unsigned char *buf,
size_t len, BN_CTX *ctx)
{
+ if (point == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
if (group->meth->point2oct == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
- return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
+ return ossl_ec_GFp_simple_point2oct(group, point, form, buf, len,
+ ctx);
else
#ifdef OPENSSL_NO_EC2M
{
- ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
- return ec_GF2m_simple_point2oct(group, point,
- form, buf, len, ctx);
+ return ossl_ec_GF2m_simple_point2oct(group, point,
+ form, buf, len, ctx);
#endif
}
@@ -103,24 +111,24 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
{
if (group->meth->oct2point == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ec_point_is_compat(point, group)) {
- ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+ ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
- return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
+ return ossl_ec_GFp_simple_oct2point(group, point, buf, len, ctx);
else
#ifdef OPENSSL_NO_EC2M
{
- ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
- return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
+ return ossl_ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
#endif
}
return group->meth->oct2point(group, point, buf, len, ctx);
@@ -137,7 +145,7 @@ size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
if (len == 0)
return 0;
if ((buf = OPENSSL_malloc(len)) == NULL) {
- ECerr(EC_F_EC_POINT_POINT2BUF, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
index 64d2cc93a620..19e2f0d0c04d 100644
--- a/crypto/ec/ec_pmeth.c
+++ b/crypto/ec/ec_pmeth.c
@@ -1,12 +1,18 @@
/*
- * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDH and ECDSA 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/asn1t.h>
@@ -43,7 +49,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
EC_PKEY_CTX *dctx;
if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
- ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -53,7 +59,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
return 1;
}
-static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
{
EC_PKEY_CTX *dctx, *sctx;
if (!pkey_ec_init(dst))
@@ -103,7 +109,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
int ret, type;
unsigned int sltmp;
EC_PKEY_CTX *dctx = ctx->data;
- EC_KEY *ec = ctx->pkey->pkey.ec;
+ /*
+ * Discard const. Its marked as const because this may be a cached copy of
+ * the "real" key. These calls don't make any modifications that need to
+ * be reflected back in the "original" key.
+ */
+ EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
const int sig_sz = ECDSA_size(ec);
/* ensure cast to size_t is safe */
@@ -116,11 +127,11 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
}
if (*siglen < (size_t)sig_sz) {
- ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
- type = (dctx->md != NULL) ? EVP_MD_type(dctx->md) : NID_sha1;
+ type = (dctx->md != NULL) ? EVP_MD_get_type(dctx->md) : NID_sha1;
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
@@ -136,10 +147,15 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
{
int ret, type;
EC_PKEY_CTX *dctx = ctx->data;
- EC_KEY *ec = ctx->pkey->pkey.ec;
+ /*
+ * Discard const. Its marked as const because this may be a cached copy of
+ * the "real" key. These calls don't make any modifications that need to
+ * be reflected back in the "original" key.
+ */
+ EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
if (dctx->md)
- type = EVP_MD_type(dctx->md);
+ type = EVP_MD_get_type(dctx->md);
else
type = NID_sha1;
@@ -155,21 +171,32 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
size_t outlen;
const EC_POINT *pubkey = NULL;
EC_KEY *eckey;
+ const EC_KEY *eckeypub;
EC_PKEY_CTX *dctx = ctx->data;
- if (!ctx->pkey || !ctx->peerkey) {
- ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+
+ if (ctx->pkey == NULL || ctx->peerkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
+ return 0;
+ }
+ eckeypub = EVP_PKEY_get0_EC_KEY(ctx->peerkey);
+ if (eckeypub == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
return 0;
}
- eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
+ eckey = dctx->co_key ? dctx->co_key
+ : (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
if (!key) {
const EC_GROUP *group;
group = EC_KEY_get0_group(eckey);
+
+ if (group == NULL)
+ return 0;
*keylen = (EC_GROUP_get_degree(group) + 7) / 8;
return 1;
}
- pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+ pubkey = EC_KEY_get0_public_key(eckeypub);
/*
* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
@@ -203,14 +230,15 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
if (!pkey_ec_derive(ctx, NULL, &ktmplen))
return 0;
if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) {
- ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
goto err;
/* Do KDF stuff */
- if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen,
- dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+ if (!ossl_ecdh_kdf_X9_63(key, *keylen, ktmp, ktmplen,
+ dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md,
+ ctx->libctx, ctx->propquery))
goto err;
rv = 1;
@@ -228,7 +256,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL) {
- ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE);
return 0;
}
EC_GROUP_free(dctx->gen_group);
@@ -237,7 +265,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_EC_PARAM_ENC:
if (!dctx->gen_group) {
- ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
+ ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET);
return 0;
}
EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
@@ -249,14 +277,23 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
if (dctx->cofactor_mode != -1)
return dctx->cofactor_mode;
else {
- EC_KEY *ec_key = ctx->pkey->pkey.ec;
+ const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ctx->pkey);
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
}
} else if (p1 < -1 || p1 > 1)
return -2;
dctx->cofactor_mode = p1;
if (p1 != -1) {
- EC_KEY *ec_key = ctx->pkey->pkey.ec;
+ EC_KEY *ec_key = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
+
+ /*
+ * We discarded the "const" above. This will only work if the key is
+ * a "real" legacy key, and not a cached copy of a provided key
+ */
+ if (evp_pkey_is_provided(ctx->pkey)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_UNSUPPORTED);
+ return 0;
+ }
if (!ec_key->group)
return -2;
/* If cofactor is 1 cofactor mode does nothing */
@@ -318,17 +355,18 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return dctx->kdf_ukmlen;
case EVP_PKEY_CTRL_MD:
- if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
- ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+ if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512 &&
+ EVP_MD_get_type((const EVP_MD *)p2) != NID_sm3) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE);
return 0;
}
dctx->md = p2;
@@ -362,7 +400,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
if (nid == NID_undef)
nid = OBJ_ln2nid(value);
if (nid == NID_undef) {
- ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE);
return 0;
}
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
@@ -378,7 +416,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
} else if (strcmp(type, "ecdh_kdf_md") == 0) {
const EVP_MD *md;
if ((md = EVP_get_digestbyname(value)) == NULL) {
- ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST);
return 0;
}
return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
@@ -398,7 +436,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
int ret;
if (dctx->gen_group == NULL) {
- ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+ ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -417,7 +455,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
int ret;
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
- ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+ ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -436,7 +474,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
return ret ? EC_KEY_generate_key(ec) : 0;
}
-const EVP_PKEY_METHOD ec_pkey_meth = {
+static const EVP_PKEY_METHOD ec_pkey_meth = {
EVP_PKEY_EC,
0,
pkey_ec_init,
@@ -474,3 +512,8 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
pkey_ec_ctrl,
pkey_ec_ctrl_str
};
+
+const EVP_PKEY_METHOD *ossl_ec_pkey_method(void)
+{
+ return &ec_pkey_meth;
+}
diff --git a/crypto/ec/ec_print.c b/crypto/ec/ec_print.c
index 660fc400fb75..ffe112052fbd 100644
--- a/crypto/ec/ec_print.c
+++ b/crypto/ec/ec_print.c
@@ -1,74 +1,16 @@
/*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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> /* strlen */
#include <openssl/crypto.h>
-#include <openssl/err.h>
#include "ec_local.h"
-BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
- const EC_POINT *point,
- point_conversion_form_t form,
- BIGNUM *ret, BN_CTX *ctx)
-{
- size_t buf_len = 0;
- unsigned char *buf;
-
- buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
-
- if (buf_len == 0)
- return NULL;
-
- ret = BN_bin2bn(buf, buf_len, ret);
-
- OPENSSL_free(buf);
-
- return ret;
-}
-
-EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
- const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
-{
- size_t buf_len = 0;
- unsigned char *buf;
- EC_POINT *ret;
-
- if ((buf_len = BN_num_bytes(bn)) == 0)
- buf_len = 1;
- if ((buf = OPENSSL_malloc(buf_len)) == NULL) {
- ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- if (!BN_bn2binpad(bn, buf, buf_len)) {
- OPENSSL_free(buf);
- return NULL;
- }
-
- if (point == NULL) {
- if ((ret = EC_POINT_new(group)) == NULL) {
- OPENSSL_free(buf);
- return NULL;
- }
- } else
- ret = point;
-
- if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
- if (ret != point)
- EC_POINT_clear_free(ret);
- OPENSSL_free(buf);
- return NULL;
- }
-
- OPENSSL_free(buf);
- return ret;
-}
-
static const char *HEX_DIGITS = "0123456789ABCDEF";
/* the return value must be freed (using OPENSSL_free()) */
@@ -105,17 +47,39 @@ char *EC_POINT_point2hex(const EC_GROUP *group,
}
EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
- const char *buf, EC_POINT *point, BN_CTX *ctx)
+ const char *hex, EC_POINT *point, BN_CTX *ctx)
{
- EC_POINT *ret = NULL;
- BIGNUM *tmp_bn = NULL;
+ int ok = 0;
+ unsigned char *oct_buf = NULL;
+ size_t len, oct_buf_len = 0;
+ EC_POINT *pt = NULL;
- if (!BN_hex2bn(&tmp_bn, buf))
+ if (group == NULL || hex == NULL)
return NULL;
- ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
-
- BN_clear_free(tmp_bn);
+ if (point == NULL) {
+ pt = EC_POINT_new(group);
+ if (pt == NULL)
+ goto err;
+ } else {
+ pt = point;
+ }
- return ret;
+ len = strlen(hex) / 2;
+ oct_buf = OPENSSL_malloc(len);
+ if (oct_buf == NULL)
+ goto err;
+
+ if (!OPENSSL_hexstr2buf_ex(oct_buf, len, &oct_buf_len, hex, '\0')
+ || !EC_POINT_oct2point(group, pt, oct_buf, oct_buf_len, ctx))
+ goto err;
+ ok = 1;
+err:
+ OPENSSL_clear_free(oct_buf, oct_buf_len);
+ if (!ok) {
+ if (pt != point)
+ EC_POINT_clear_free(pt);
+ pt = NULL;
+ }
+ return pt;
}
diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c
index 96efac62f66f..de63bf8500b4 100644
--- a/crypto/ec/ecdh_kdf.c
+++ b/crypto/ec/ecdh_kdf.c
@@ -1,81 +1,65 @@
/*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDH low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
+#include <openssl/core_names.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
+#include <openssl/kdf.h>
#include "ec_local.h"
/* Key derivation function from X9.63/SECG */
-/* Way more than we will ever need */
-#define ECDH_KDF_MAX (1 << 30)
-
-int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
- const unsigned char *Z, size_t Zlen,
- const unsigned char *sinfo, size_t sinfolen,
- const EVP_MD *md)
+int ossl_ecdh_kdf_X9_63(unsigned char *out, size_t outlen,
+ const unsigned char *Z, size_t Zlen,
+ const unsigned char *sinfo, size_t sinfolen,
+ const EVP_MD *md,
+ OSSL_LIB_CTX *libctx, const char *propq)
{
- EVP_MD_CTX *mctx = NULL;
- int rv = 0;
- unsigned int i;
- size_t mdlen;
- unsigned char ctr[4];
- if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
- || Zlen > ECDH_KDF_MAX)
- return 0;
- mctx = EVP_MD_CTX_new();
- if (mctx == NULL)
- return 0;
- mdlen = EVP_MD_size(md);
- for (i = 1;; i++) {
- unsigned char mtmp[EVP_MAX_MD_SIZE];
- if (!EVP_DigestInit_ex(mctx, md, NULL))
- goto err;
- ctr[3] = i & 0xFF;
- ctr[2] = (i >> 8) & 0xFF;
- ctr[1] = (i >> 16) & 0xFF;
- ctr[0] = (i >> 24) & 0xFF;
- if (!EVP_DigestUpdate(mctx, Z, Zlen))
- goto err;
- if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
- goto err;
- if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
- goto err;
- if (outlen >= mdlen) {
- if (!EVP_DigestFinal(mctx, out, NULL))
- goto err;
- outlen -= mdlen;
- if (outlen == 0)
- break;
- out += mdlen;
- } else {
- if (!EVP_DigestFinal(mctx, mtmp, NULL))
- goto err;
- memcpy(out, mtmp, outlen);
- OPENSSL_cleanse(mtmp, mdlen);
- break;
- }
+ int ret = 0;
+ EVP_KDF_CTX *kctx = NULL;
+ OSSL_PARAM params[4], *p = params;
+ const char *mdname = EVP_MD_get0_name(md);
+ EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X963KDF, propq);
+
+ if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) {
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ (char *)mdname, 0);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ (void *)Z, Zlen);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
+ (void *)sinfo, sinfolen);
+ *p = OSSL_PARAM_construct_end();
+
+ ret = EVP_KDF_derive(kctx, out, outlen, params) > 0;
+ EVP_KDF_CTX_free(kctx);
}
- rv = 1;
- err:
- EVP_MD_CTX_free(mctx);
- return rv;
+ EVP_KDF_free(kdf);
+ return ret;
}
/*-
* The old name for ecdh_KDF_X9_63
* Retained for ABI compatibility
*/
+#ifndef OPENSSL_NO_DEPRECATED_3_0
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
{
- return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md);
+ return ossl_ecdh_kdf_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md, NULL,
+ NULL);
}
+#endif
diff --git a/crypto/ec/ecdh_ossl.c b/crypto/ec/ecdh_ossl.c
index 0be00d43da4e..8016c6d7ad73 100644
--- a/crypto/ec/ecdh_ossl.c
+++ b/crypto/ec/ecdh_ossl.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDH low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include <limits.h>
@@ -23,7 +29,7 @@ int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
const EC_POINT *pub_key, const EC_KEY *ecdh)
{
if (ecdh->group->meth->ecdh_compute_key == NULL) {
- ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
return 0;
}
@@ -31,12 +37,17 @@ int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
}
/*-
- * This implementation is based on the following primitives in the IEEE 1363 standard:
+ * This implementation is based on the following primitives in the
+ * IEEE 1363 standard:
* - ECKAS-DH1
* - ECSVDP-DH
+ *
+ * It also conforms to SP800-56A r3
+ * See Section 5.7.1.2 "Elliptic Curve Cryptography Cofactor Diffie-Hellman
+ * (ECC CDH) Primitive:". The steps listed below refer to SP800-56A.
*/
-int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
- const EC_POINT *pub_key, const EC_KEY *ecdh)
+int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
+ const EC_POINT *pub_key, const EC_KEY *ecdh)
{
BN_CTX *ctx;
EC_POINT *tmp = NULL;
@@ -47,61 +58,74 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
size_t buflen, len;
unsigned char *buf = NULL;
- if ((ctx = BN_CTX_new()) == NULL)
+ if ((ctx = BN_CTX_new_ex(ecdh->libctx)) == NULL)
goto err;
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
if (x == NULL) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
priv_key = EC_KEY_get0_private_key(ecdh);
if (priv_key == NULL) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
goto err;
}
group = EC_KEY_get0_group(ecdh);
+ /*
+ * Step(1) - Compute the point tmp = cofactor * owners_private_key
+ * * peer_public_key.
+ */
if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
if (!EC_GROUP_get_cofactor(group, x, NULL) ||
!BN_mul(x, x, priv_key, ctx)) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
priv_key = x;
}
if ((tmp = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
+ /*
+ * Step(2) : If point tmp is at infinity then clear intermediate values and
+ * exit. Note: getting affine coordinates returns 0 if point is at infinity.
+ * Step(3a) : Get x-coordinate of point x = tmp.x
+ */
if (!EC_POINT_get_affine_coordinates(group, tmp, x, NULL, ctx)) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
+ /*
+ * Step(3b) : convert x to a byte string, using the field-element-to-byte
+ * string conversion routine defined in Appendix C.2
+ */
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
len = BN_num_bytes(x);
if (len > buflen) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
if ((buf = OPENSSL_malloc(buflen)) == NULL) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(buf, 0, buflen - len);
if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
- ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -112,6 +136,8 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
ret = 1;
err:
+ /* Step(4) : Destroy all intermediate calculations */
+ BN_clear(x);
EC_POINT_clear_free(tmp);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c
index 1da87bfb5e39..775b7ec911be 100644
--- a/crypto/ec/ecdsa_ossl.c
+++ b/crypto/ec/ecdsa_ossl.c
@@ -1,12 +1,18 @@
/*
- * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include <openssl/err.h>
#include <openssl/obj_mac.h>
@@ -14,18 +20,67 @@
#include "crypto/bn.h"
#include "ec_local.h"
+#define MIN_ECDSA_SIGN_ORDERBITS 64
+/*
+ * It is highly unlikely that a retry will happen,
+ * Multiple retries would indicate that something is wrong
+ * with the group parameters (which would normally only happen
+ * with a bad custom group).
+ */
+#define MAX_ECDSA_SIGN_RETRIES 8
+
+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp)
+{
+ if (eckey->group->meth->ecdsa_sign_setup == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA);
+ return 0;
+ }
+
+ return eckey->group->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
+}
+
+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey)
+{
+ if (eckey->group->meth->ecdsa_sign_sig == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA);
+ return NULL;
+ }
+
+ return eckey->group->meth->ecdsa_sign_sig(dgst, dgst_len,
+ in_kinv, in_r, eckey);
+}
+
+int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+ if (eckey->group->meth->ecdsa_verify_sig == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA);
+ return 0;
+ }
+
+ return eckey->group->meth->ecdsa_verify_sig(dgst, dgst_len, sig, eckey);
+}
+
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen,
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
{
ECDSA_SIG *s;
+ if (sig == NULL && (kinv == NULL || r == NULL)) {
+ *siglen = ECDSA_size(eckey);
+ return 1;
+ }
+
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL) {
*siglen = 0;
return 0;
}
- *siglen = i2d_ECDSA_SIG(s, &sig);
+ *siglen = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL);
ECDSA_SIG_free(s);
return 1;
}
@@ -44,42 +99,48 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
const BIGNUM *priv_key;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
return 0;
}
if (!EC_KEY_can_sign(eckey)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
return 0;
}
if ((ctx = ctx_in) == NULL) {
- if ((ctx = BN_CTX_new()) == NULL) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+ if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
}
- k = BN_new(); /* this value is later returned in *kinvp */
+ k = BN_secure_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
X = BN_new();
if (k == NULL || r == NULL || X == NULL) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if ((tmp_point = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ if ((order = EC_GROUP_get0_order(group)) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
- order = EC_GROUP_get0_order(group);
/* Preallocate space */
order_bits = BN_num_bits(order);
- if (!BN_set_bit(k, order_bits)
+ /* Check the number of bits here so that an infinite loop is not possible */
+ if (order_bits < MIN_ECDSA_SIGN_ORDERBITS
+ || !BN_set_bit(k, order_bits)
|| !BN_set_bit(r, order_bits)
|| !BN_set_bit(X, order_bits))
goto err;
@@ -88,41 +149,39 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
/* get random k */
do {
if (dgst != NULL) {
- if (!BN_generate_dsa_nonce(k, order, priv_key,
- dgst, dlen, ctx)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP,
- EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+ if (!ossl_bn_gen_dsa_nonce_fixed_top(k, order, priv_key,
+ dgst, dlen, ctx)) {
+ ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
} else {
- if (!BN_priv_rand_range(k, order)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP,
- EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+ if (!ossl_bn_priv_rand_range_fixed_top(k, order, 0, ctx)) {
+ ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
}
- } while (BN_is_zero(k));
+ } while (ossl_bn_is_word_fixed_top(k, 0));
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates(group, tmp_point, X, NULL, ctx)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(r, X, order, ctx)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(r));
/* compute the inverse of k */
- if (!ec_group_do_inverse_ord(group, k, k, ctx)) {
- ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+ if (!ossl_ec_group_do_inverse_ord(group, k, k, ctx)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -145,17 +204,18 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
return ret;
}
-int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
- BIGNUM **rp)
+int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp)
{
return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
}
-ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
- const BIGNUM *in_kinv, const BIGNUM *in_r,
- EC_KEY *eckey)
+ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey)
{
int ok = 0, i;
+ int retries = 0;
BIGNUM *kinv = NULL, *s, *m = NULL;
const BIGNUM *order, *ckinv;
BN_CTX *ctx = NULL;
@@ -167,39 +227,43 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
priv_key = EC_KEY_get0_private_key(eckey);
if (group == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (priv_key == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
return NULL;
}
if (!EC_KEY_can_sign(eckey)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
return NULL;
}
ret = ECDSA_SIG_new();
if (ret == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->r = BN_new();
ret->s = BN_new();
if (ret->r == NULL || ret->s == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
s = ret->s;
- if ((ctx = BN_CTX_new()) == NULL
+ if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL
|| (m = BN_new()) == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if ((order = EC_GROUP_get0_order(group)) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
- order = EC_GROUP_get0_order(group);
i = BN_num_bits(order);
/*
* Need to truncate digest if it is too long: first truncate whole bytes.
@@ -207,25 +271,25 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
if (8 * dgst_len > i)
dgst_len = (i + 7) / 8;
if (!BN_bin2bn(dgst, dgst_len, m)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* If still too long, truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
do {
if (in_kinv == NULL || in_r == NULL) {
if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB);
goto err;
}
ckinv = kinv;
} else {
ckinv = in_kinv;
if (BN_copy(ret->r, in_r) == NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -239,11 +303,11 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
*/
if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx)
|| !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (!bn_mod_add_fixed_top(s, s, m, order)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/*
@@ -252,7 +316,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
*/
if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx)
|| !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -262,7 +326,12 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
* generate new kinv and r values
*/
if (in_kinv != NULL && in_r != NULL) {
- ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
+ ERR_raise(ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES);
+ goto err;
+ }
+ /* Avoid infinite loops cause by invalid group parameters */
+ if (retries++ > MAX_ECDSA_SIGN_RETRIES) {
+ ERR_raise(ERR_LIB_EC, EC_R_TOO_MANY_RETRIES);
goto err;
}
} else {
@@ -314,8 +383,8 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
return ret;
}
-int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
- const ECDSA_SIG *sig, EC_KEY *eckey)
+int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey)
{
int ret = -1, i;
BN_CTX *ctx;
@@ -328,18 +397,18 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
/* check input values */
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return -1;
}
if (!EC_KEY_can_sign(eckey)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
return -1;
}
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(eckey->libctx);
if (ctx == NULL) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return -1;
}
BN_CTX_start(ctx);
@@ -348,26 +417,26 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
if (X == NULL) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
order = EC_GROUP_get0_order(group);
if (order == NULL) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
+ ERR_raise(ERR_LIB_EC, EC_R_BAD_SIGNATURE);
ret = 0; /* signature is invalid */
goto err;
}
/* calculate tmp1 = inv(S) mod order */
- if (!ec_group_do_inverse_ord(group, u2, sig->s, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ if (!ossl_ec_group_do_inverse_ord(group, u2, sig->s, ctx)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* digest -> m */
@@ -378,41 +447,41 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
if (8 * dgst_len > i)
dgst_len = (i + 7) / 8;
if (!BN_bin2bn(dgst, dgst_len, m)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* u2 = r * w mod q */
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if ((point = EC_POINT_new(group)) == NULL) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(u1, X, order, ctx)) {
- ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* if the signature is correct u1 is equal to sig->r */
diff --git a/crypto/ec/ecdsa_sign.c b/crypto/ec/ecdsa_sign.c
index dc79c8c8e3df..0c0748c84f87 100644
--- a/crypto/ec/ecdsa_sign.c
+++ b/crypto/ec/ecdsa_sign.c
@@ -1,12 +1,18 @@
/*
- * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/ec.h>
#include "ec_local.h"
#include <openssl/err.h>
@@ -22,7 +28,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
{
if (eckey->meth->sign_sig != NULL)
return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
- ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return NULL;
}
@@ -38,7 +44,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
{
if (eckey->meth->sign != NULL)
return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
- ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
}
@@ -47,6 +53,6 @@ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
{
if (eckey->meth->sign_setup != NULL)
return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
- ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
}
diff --git a/crypto/ec/ecdsa_vrf.c b/crypto/ec/ecdsa_vrf.c
index ff597bdc143c..c148ecdb7cf6 100644
--- a/crypto/ec/ecdsa_vrf.c
+++ b/crypto/ec/ecdsa_vrf.c
@@ -1,12 +1,18 @@
/*
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/ec.h>
#include "ec_local.h"
#include <openssl/err.h>
@@ -22,7 +28,7 @@ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
{
if (eckey->meth->verify_sig != NULL)
return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey);
- ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return -1;
}
@@ -38,6 +44,6 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
if (eckey->meth->verify != NULL)
return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
eckey);
- ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
+ ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
return -1;
}
diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c
index b538fadcb10c..96ced7c8be0d 100644
--- a/crypto/ec/eck_prn.c
+++ b/crypto/ec/eck_prn.c
@@ -1,27 +1,30 @@
/*
- * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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 "internal/deprecated.h"
+
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
-#ifndef OPENSSL_NO_STDIO
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+# ifndef OPENSSL_NO_STDIO
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BUF_LIB);
return 0;
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
@@ -36,7 +39,7 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BIO_LIB);
return 0;
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
@@ -51,7 +54,7 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
- ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BIO_LIB);
return 0;
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
@@ -59,7 +62,7 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
BIO_free(b);
return ret;
}
-#endif
+#endif /* OPENSSL_NO_STDIO */
static int print_bin(BIO *fp, const char *str, const unsigned char *num,
size_t len, int off);
@@ -69,10 +72,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
int ret = 0, reason = ERR_R_BIO_LIB;
BN_CTX *ctx = NULL;
const EC_POINT *point = NULL;
- BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL;
+ unsigned char *gen_buf = NULL;
const BIGNUM *order = NULL, *cofactor = NULL;
const unsigned char *seed;
- size_t seed_len = 0;
+ size_t seed_len = 0, gen_buf_len = 0;
static const char *gen_compressed = "Generator (compressed):";
static const char *gen_uncompressed = "Generator (uncompressed):";
@@ -112,10 +116,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
goto err;
}
} else {
+ const char *form_str;
/* explicit parameters */
int is_char_two = 0;
point_conversion_form_t form;
- int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
+ int tmp_nid = EC_GROUP_get_field_type(x);
if (tmp_nid == NID_X9_62_characteristic_two_field)
is_char_two = 1;
@@ -144,7 +149,8 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
form = EC_GROUP_get_point_conversion_form(x);
- if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
+ gen_buf_len = EC_POINT_point2buf(x, point, form, &gen_buf, ctx);
+ if (gen_buf_len == 0) {
reason = ERR_R_EC_LIB;
goto err;
}
@@ -185,22 +191,18 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
goto err;
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, NULL, off))
goto err;
- if (form == POINT_CONVERSION_COMPRESSED) {
- if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
- NULL, off))
- goto err;
- } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
- if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
- NULL, off))
- goto err;
- } else { /* form == POINT_CONVERSION_HYBRID */
- if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
- NULL, off))
- goto err;
- }
- if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
- NULL, off))
+ if (form == POINT_CONVERSION_COMPRESSED)
+ form_str = gen_compressed;
+ else if (form == POINT_CONVERSION_UNCOMPRESSED)
+ form_str = gen_uncompressed;
+ else
+ form_str = gen_hybrid;
+ if (gen_buf != NULL
+ && !print_bin(bp, form_str, gen_buf, gen_buf_len, off))
+ goto err;
+
+ if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, NULL, off))
goto err;
if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
NULL, off))
@@ -211,11 +213,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
ret = 1;
err:
if (!ret)
- ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
+ ERR_raise(ERR_LIB_EC, reason);
BN_free(p);
BN_free(a);
BN_free(b);
- BN_free(gen);
+ OPENSSL_clear_free(gen_buf, gen_buf_len);
BN_CTX_free(ctx);
return ret;
}
@@ -257,3 +259,4 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
return 1;
}
+#endif /* OPENSSL_NO_DEPRECATED_3_0 */
diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c
index bdc39d5efb0e..35b492453f57 100644
--- a/crypto/ec/ecp_mont.c
+++ b/crypto/ec/ecp_mont.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
#include "ec_local.h"
@@ -17,98 +23,99 @@ const EC_METHOD *EC_GFp_mont_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_mont_group_init,
- ec_GFp_mont_group_finish,
- ec_GFp_mont_group_clear_finish,
- ec_GFp_mont_group_copy,
- ec_GFp_mont_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
+ ossl_ec_GFp_mont_group_init,
+ ossl_ec_GFp_mont_group_finish,
+ ossl_ec_GFp_mont_group_clear_finish,
+ ossl_ec_GFp_mont_group_copy,
+ ossl_ec_GFp_mont_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_simple_point_get_affine_coordinates,
0, 0, 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
0 /* mul */ ,
0 /* precompute_mult */ ,
0 /* have_precompute_mult */ ,
- ec_GFp_mont_field_mul,
- ec_GFp_mont_field_sqr,
+ ossl_ec_GFp_mont_field_mul,
+ ossl_ec_GFp_mont_field_sqr,
0 /* field_div */ ,
- ec_GFp_mont_field_inv,
- ec_GFp_mont_field_encode,
- ec_GFp_mont_field_decode,
- ec_GFp_mont_field_set_to_one,
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_GFp_mont_field_inv,
+ ossl_ec_GFp_mont_field_encode,
+ ossl_ec_GFp_mont_field_decode,
+ ossl_ec_GFp_mont_field_set_to_one,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
- ec_GFp_simple_blind_coordinates,
- ec_GFp_simple_ladder_pre,
- ec_GFp_simple_ladder_step,
- ec_GFp_simple_ladder_post
+ ossl_ec_GFp_simple_blind_coordinates,
+ ossl_ec_GFp_simple_ladder_pre,
+ ossl_ec_GFp_simple_ladder_step,
+ ossl_ec_GFp_simple_ladder_post
};
return &ret;
}
-int ec_GFp_mont_group_init(EC_GROUP *group)
+int ossl_ec_GFp_mont_group_init(EC_GROUP *group)
{
int ok;
- ok = ec_GFp_simple_group_init(group);
+ ok = ossl_ec_GFp_simple_group_init(group);
group->field_data1 = NULL;
group->field_data2 = NULL;
return ok;
}
-void ec_GFp_mont_group_finish(EC_GROUP *group)
+void ossl_ec_GFp_mont_group_finish(EC_GROUP *group)
{
BN_MONT_CTX_free(group->field_data1);
group->field_data1 = NULL;
BN_free(group->field_data2);
group->field_data2 = NULL;
- ec_GFp_simple_group_finish(group);
+ ossl_ec_GFp_simple_group_finish(group);
}
-void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
+void ossl_ec_GFp_mont_group_clear_finish(EC_GROUP *group)
{
BN_MONT_CTX_free(group->field_data1);
group->field_data1 = NULL;
BN_clear_free(group->field_data2);
group->field_data2 = NULL;
- ec_GFp_simple_group_clear_finish(group);
+ ossl_ec_GFp_simple_group_clear_finish(group);
}
-int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+int ossl_ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
BN_MONT_CTX_free(dest->field_data1);
dest->field_data1 = NULL;
BN_clear_free(dest->field_data2);
dest->field_data2 = NULL;
- if (!ec_GFp_simple_group_copy(dest, src))
+ if (!ossl_ec_GFp_simple_group_copy(dest, src))
return 0;
if (src->field_data1 != NULL) {
@@ -132,8 +139,9 @@ int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
return 0;
}
-int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BN_MONT_CTX *mont = NULL;
@@ -146,7 +154,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
group->field_data2 = NULL;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -155,7 +163,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
if (mont == NULL)
goto err;
if (!BN_MONT_CTX_set(mont, p, ctx)) {
- ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
one = BN_new();
@@ -169,7 +177,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
group->field_data2 = one;
one = NULL;
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
if (!ret) {
BN_MONT_CTX_free(group->field_data1);
@@ -185,22 +193,22 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
return ret;
}
-int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
}
-int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -212,8 +220,8 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
* We have a Mont structure, so SCA hardening is FLT inversion.
*/
-int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
{
BIGNUM *e = NULL;
BN_CTX *new_ctx = NULL;
@@ -222,7 +230,8 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
if (group->field_data1 == NULL)
return 0;
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
+ if (ctx == NULL
+ && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL)
return 0;
BN_CTX_start(ctx);
@@ -243,7 +252,7 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
/* throw an error on zero */
if (BN_is_zero(r)) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_INV, EC_R_CANNOT_INVERT);
+ ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT);
goto err;
}
@@ -255,33 +264,33 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
return ret;
}
-int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
- const BIGNUM *a, BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
}
-int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
- const BIGNUM *a, BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_from_montgomery(r, a, group->field_data1, ctx);
}
-int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
- BN_CTX *ctx)
+int ossl_ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
+ BN_CTX *ctx)
{
if (group->field_data2 == NULL) {
- ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED);
return 0;
}
diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c
index 9fd01279a891..3efd43e64c75 100644
--- a/crypto/ec/ecp_nist.c
+++ b/crypto/ec/ecp_nist.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <limits.h>
#include <openssl/err.h>
@@ -19,77 +25,79 @@ const EC_METHOD *EC_GFp_nist_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_nist_group_copy,
- ec_GFp_nist_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
+ ossl_ec_GFp_simple_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_nist_group_copy,
+ ossl_ec_GFp_nist_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_simple_point_get_affine_coordinates,
0, 0, 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
0 /* mul */ ,
0 /* precompute_mult */ ,
0 /* have_precompute_mult */ ,
- ec_GFp_nist_field_mul,
- ec_GFp_nist_field_sqr,
+ ossl_ec_GFp_nist_field_mul,
+ ossl_ec_GFp_nist_field_sqr,
0 /* field_div */ ,
- ec_GFp_simple_field_inv,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
- ec_GFp_simple_blind_coordinates,
- ec_GFp_simple_ladder_pre,
- ec_GFp_simple_ladder_step,
- ec_GFp_simple_ladder_post
+ ossl_ec_GFp_simple_blind_coordinates,
+ ossl_ec_GFp_simple_ladder_pre,
+ ossl_ec_GFp_simple_ladder_step,
+ ossl_ec_GFp_simple_ladder_post
};
return &ret;
}
-int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+int ossl_ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
dest->field_mod_func = src->field_mod_func;
- return ec_GFp_simple_group_copy(dest, src);
+ return ossl_ec_GFp_simple_group_copy(dest, src);
}
-int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ if ((ctx = new_ctx = BN_CTX_new_ex(group->libctx)) == NULL)
return 0;
BN_CTX_start(ctx);
@@ -105,11 +113,11 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
group->field_mod_func = BN_nist_mod_521;
else {
- ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
+ ERR_raise(ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME);
goto err;
}
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
err:
BN_CTX_end(ctx);
@@ -117,18 +125,18 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
return ret;
}
-int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *ctx_new = NULL;
if (!group || !r || !a || !b) {
- ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
- if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+ if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL)
goto err;
if (!BN_mul(r, a, b, ctx))
@@ -142,18 +150,18 @@ int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
return ret;
}
-int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
{
int ret = 0;
BN_CTX *ctx_new = NULL;
if (!group || !r || !a) {
- ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
- if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+ if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL)
goto err;
if (!BN_sqr(r, a, ctx))
diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c
index 6f7d66c8bea4..5ab0dd7bef4f 100644
--- a/crypto/ec/ecp_nistp224.c
+++ b/crypto/ec/ecp_nistp224.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -24,6 +24,12 @@
*/
/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+/*
* A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
*
* Inspired by Daniel J. Bernstein's public domain nistp224 implementation
@@ -31,22 +37,17 @@
*/
#include <openssl/opensslconf.h>
-#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-NON_EMPTY_TRANSLATION_UNIT
-#else
-
-# include <stdint.h>
-# include <string.h>
-# include <openssl/err.h>
-# include "ec_local.h"
-
-# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
- /* even with gcc, the typedef won't work for 32-bit platforms */
-typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
- * platforms */
-# else
-# error "Your compiler doesn't appear to support 128-bit integer types"
-# endif
+
+#include <stdint.h>
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_local.h"
+
+#include "internal/numbers.h"
+
+#ifndef INT128_MAX
+# error "Your compiler doesn't appear to support 128-bit integer types"
+#endif
typedef uint8_t u8;
typedef uint64_t u64;
@@ -245,54 +246,55 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_nistp224_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_nist_group_copy,
- ec_GFp_nistp224_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_nistp224_point_get_affine_coordinates,
+ ossl_ec_GFp_nistp224_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_nist_group_copy,
+ ossl_ec_GFp_nistp224_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_nistp224_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */ ,
0 /* point2oct */ ,
0 /* oct2point */ ,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- ec_GFp_nistp224_points_mul,
- ec_GFp_nistp224_precompute_mult,
- ec_GFp_nistp224_have_precompute_mult,
- ec_GFp_nist_field_mul,
- ec_GFp_nist_field_sqr,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_nistp224_points_mul,
+ ossl_ec_GFp_nistp224_precompute_mult,
+ ossl_ec_GFp_nistp224_have_precompute_mult,
+ ossl_ec_GFp_nist_field_mul,
+ ossl_ec_GFp_nist_field_sqr,
0 /* field_div */ ,
- ec_GFp_simple_field_inv,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
0, /* ladder_pre */
@@ -332,12 +334,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
int num_bytes;
if (BN_is_negative(bn)) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
if (num_bytes < 0) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin28_to_felem(out, b_out);
@@ -663,7 +665,9 @@ static void felem_contract(felem out, const felem in)
*/
static void felem_neg(felem out, const felem in)
{
- widefelem tmp = {0};
+ widefelem tmp;
+
+ memset(tmp, 0, sizeof(tmp));
felem_diff_128_64(tmp, in);
felem_reduce(out, tmp);
}
@@ -1201,7 +1205,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
bits |= get_bit(scalars[num], i + 1) << 2;
bits |= get_bit(scalars[num], i) << 1;
bits |= get_bit(scalars[num], i - 1);
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+ ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
/* select the point to add or subtract */
select_point(digit, 17, pre_comp[num], tmp);
@@ -1235,7 +1239,7 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new(void)
NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
if (!ret) {
- ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
@@ -1243,7 +1247,7 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new(void)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
@@ -1266,7 +1270,7 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
return;
CRYPTO_DOWN_REF(&p->references, &i, p->lock);
- REF_PRINT_COUNT("EC_nistp224", x);
+ REF_PRINT_COUNT("EC_nistp224", p);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
@@ -1280,25 +1284,29 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
* OPENSSL EC_METHOD FUNCTIONS
*/
-int ec_GFp_nistp224_group_init(EC_GROUP *group)
+int ossl_ec_GFp_nistp224_group_init(EC_GROUP *group)
{
int ret;
- ret = ec_GFp_simple_group_init(group);
+ ret = ossl_ec_GFp_simple_group_init(group);
group->a_is_minus3 = 1;
return ret;
}
-int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
int ret = 0;
- BN_CTX *new_ctx = NULL;
BIGNUM *curve_p, *curve_a, *curve_b;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
curve_p = BN_CTX_get(ctx);
curve_a = BN_CTX_get(ctx);
@@ -1309,15 +1317,16 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
- ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
- EC_R_WRONG_CURVE_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
group->field_mod_func = BN_nist_mod_224;
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -1325,17 +1334,16 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
* Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
* (X/Z^2, Y/Z^3)
*/
-int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
felem z1, z2, x_in, y_in, x_out, y_out;
widefelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
@@ -1349,8 +1357,7 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(x_out, x_in);
if (x != NULL) {
if (!felem_to_BN(x, x_out)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1361,8 +1368,7 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(y_out, y_in);
if (y != NULL) {
if (!felem_to_BN(y, y_out)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1376,36 +1382,36 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3],
* Runs in constant time, unless an input is the point at infinity (which
* normally shouldn't happen).
*/
- ec_GFp_nistp_points_make_affine_internal(num,
- points,
- sizeof(felem),
- tmp_felems,
- (void (*)(void *))felem_one,
- felem_is_zero_int,
- (void (*)(void *, const void *))
- felem_assign,
- (void (*)(void *, const void *))
- felem_square_reduce, (void (*)
- (void *,
- const void
- *,
- const void
- *))
- felem_mul_reduce,
- (void (*)(void *, const void *))
- felem_inv,
- (void (*)(void *, const void *))
- felem_contract);
+ ossl_ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *))felem_one,
+ felem_is_zero_int,
+ (void (*)(void *, const void *))
+ felem_assign,
+ (void (*)(void *, const void *))
+ felem_square_reduce, (void (*)
+ (void *,
+ const void
+ *,
+ const void
+ *))
+ felem_mul_reduce,
+ (void (*)(void *, const void *))
+ felem_inv,
+ (void (*)(void *, const void *))
+ felem_contract);
}
/*
* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
* values Result is stored in r (r can equal one of the inputs).
*/
-int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
{
int ret = 0;
int j;
@@ -1449,12 +1455,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
!felem_to_BN(y, g_pre_comp[0][1][1]) ||
!felem_to_BN(z, g_pre_comp[0][1][2])) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
- generator, x, y, z,
- ctx))
+ if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group,
+ generator,
+ x, y, z, ctx))
goto err;
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
/* precomputation matches generator */
@@ -1482,7 +1488,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
OPENSSL_malloc(sizeof(felem) * (num_points * 17 + 1));
if ((secrets == NULL) || (pre_comp == NULL)
|| (mixed && (tmp_felems == NULL))) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1509,7 +1515,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar,
@@ -1519,7 +1525,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */
@@ -1561,7 +1567,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
@@ -1585,10 +1591,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_contract(z_in, z_out);
if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
(!felem_to_BN(z, z_in))) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+ ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z,
+ ctx);
err:
BN_CTX_end(ctx);
@@ -1599,21 +1606,28 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
return ret;
}
-int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
NISTP224_PRE_COMP *pre = NULL;
int i, j;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
EC_POINT *generator = NULL;
felem tmp_felems[32];
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
/* throw away old precomputation */
EC_pre_comp_free(group);
+
+#ifndef FIPS_MODULE
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -1721,14 +1735,14 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
EC_nistp224_pre_comp_free(pre);
return ret;
}
-int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
+int ossl_ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
{
return HAVEPRECOMP(group, nistp224);
}
-
-#endif
diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c
index e23e9d2a0b34..4a55f925c465 100644
--- a/crypto/ec/ecp_nistp256.c
+++ b/crypto/ec/ecp_nistp256.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -24,6 +24,12 @@
*/
/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+/*
* A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
*
* OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
@@ -32,23 +38,17 @@
*/
#include <openssl/opensslconf.h>
-#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-NON_EMPTY_TRANSLATION_UNIT
-#else
-
-# include <stdint.h>
-# include <string.h>
-# include <openssl/err.h>
-# include "ec_local.h"
-
-# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
- /* even with gcc, the typedef won't work for 32-bit platforms */
-typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
- * platforms */
-typedef __int128_t int128_t;
-# else
-# error "Your compiler doesn't appear to support 128-bit integer types"
-# endif
+
+#include <stdint.h>
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_local.h"
+
+#include "internal/numbers.h"
+
+#ifndef INT128_MAX
+# error "Your compiler doesn't appear to support 128-bit integer types"
+#endif
typedef uint8_t u8;
typedef uint32_t u32;
@@ -56,7 +56,7 @@ typedef uint64_t u64;
/*
* The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
- * can serialise an element of this field into 32 bytes. We call this an
+ * can serialize an element of this field into 32 bytes. We call this an
* felem_bytearray.
*/
@@ -110,7 +110,7 @@ static const felem_bytearray nistp256_curve_params[5] = {
* values are used as intermediate values before multiplication.
*/
-# define NLIMBS 4
+#define NLIMBS 4
typedef uint128_t limb;
typedef limb felem[NLIMBS];
@@ -135,7 +135,7 @@ static void bin32_to_felem(felem out, const u8 in[32])
}
/*
- * smallfelem_to_bin32 takes a smallfelem and serialises into a little
+ * smallfelem_to_bin32 takes a smallfelem and serializes into a little
* endian, 32 byte array. This assumes that the CPU is little-endian.
*/
static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
@@ -153,12 +153,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
int num_bytes;
if (BN_is_negative(bn)) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
if (num_bytes < 0) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin32_to_felem(out, b_out);
@@ -242,9 +242,9 @@ static void longfelem_scalar(longfelem out, const u64 scalar)
out[7] *= scalar;
}
-# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
-# define two105 (((limb)1) << 105)
-# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
+#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
+#define two105 (((limb)1) << 105)
+#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
/* zero105 is 0 mod p */
static const felem zero105 =
@@ -287,9 +287,9 @@ static void felem_diff(felem out, const felem in)
out[3] -= in[3];
}
-# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
-# define two107 (((limb)1) << 107)
-# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
+#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
+#define two107 (((limb)1) << 107)
+#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
/* zero107 is 0 mod p */
static const felem zero107 =
@@ -358,10 +358,10 @@ static void longfelem_diff(longfelem out, const longfelem in)
out[7] -= in[7];
}
-# define two64m0 (((limb)1) << 64) - 1
-# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
-# define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
-# define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
+#define two64m0 (((limb)1) << 64) - 1
+#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
+#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
+#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
/* zero110 is 0 mod p */
static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
@@ -711,9 +711,9 @@ static void felem_small_mul(longfelem out, const smallfelem small1,
smallfelem_mul(out, small1, small2);
}
-# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
-# define two100 (((limb)1) << 100)
-# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
+#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
+#define two100 (((limb)1) << 100)
+#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
/* zero100 is 0 mod p */
static const felem zero100 =
{ two100m36m4, two100, two100m36p4, two100m36p4 };
@@ -1740,7 +1740,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
bits |= get_bit(scalars[num], i + 1) << 2;
bits |= get_bit(scalars[num], i) << 1;
bits |= get_bit(scalars[num], i - 1);
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+ ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
/*
* select the point to add or subtract, in constant time
@@ -1781,54 +1781,55 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_nistp256_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_nist_group_copy,
- ec_GFp_nistp256_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_nistp256_point_get_affine_coordinates,
+ ossl_ec_GFp_nistp256_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_nist_group_copy,
+ ossl_ec_GFp_nistp256_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_nistp256_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */ ,
0 /* point2oct */ ,
0 /* oct2point */ ,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- ec_GFp_nistp256_points_mul,
- ec_GFp_nistp256_precompute_mult,
- ec_GFp_nistp256_have_precompute_mult,
- ec_GFp_nist_field_mul,
- ec_GFp_nist_field_sqr,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_nistp256_points_mul,
+ ossl_ec_GFp_nistp256_precompute_mult,
+ ossl_ec_GFp_nistp256_have_precompute_mult,
+ ossl_ec_GFp_nist_field_mul,
+ ossl_ec_GFp_nist_field_sqr,
0 /* field_div */ ,
- ec_GFp_simple_field_inv,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
0, /* ladder_pre */
@@ -1849,7 +1850,7 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void)
NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
@@ -1857,7 +1858,7 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
@@ -1880,7 +1881,7 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
return;
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
- REF_PRINT_COUNT("EC_nistp256", x);
+ REF_PRINT_COUNT("EC_nistp256", pre);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
@@ -1894,25 +1895,29 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
* OPENSSL EC_METHOD FUNCTIONS
*/
-int ec_GFp_nistp256_group_init(EC_GROUP *group)
+int ossl_ec_GFp_nistp256_group_init(EC_GROUP *group)
{
int ret;
- ret = ec_GFp_simple_group_init(group);
+ ret = ossl_ec_GFp_simple_group_init(group);
group->a_is_minus3 = 1;
return ret;
}
-int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
int ret = 0;
- BN_CTX *new_ctx = NULL;
BIGNUM *curve_p, *curve_a, *curve_b;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
curve_p = BN_CTX_get(ctx);
curve_a = BN_CTX_get(ctx);
@@ -1923,15 +1928,16 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
- ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
- EC_R_WRONG_CURVE_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
group->field_mod_func = BN_nist_mod_256;
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -1939,18 +1945,17 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
* Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
* (X/Z^2, Y/Z^3)
*/
-int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
felem z1, z2, x_in, y_in;
smallfelem x_out, y_out;
longfelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
@@ -1964,8 +1969,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(x_out, x_in);
if (x != NULL) {
if (!smallfelem_to_BN(x, x_out)) {
- ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1976,8 +1980,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(y_out, y_in);
if (y != NULL) {
if (!smallfelem_to_BN(y, y_out)) {
- ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1992,35 +1995,35 @@ static void make_points_affine(size_t num, smallfelem points[][3],
* Runs in constant time, unless an input is the point at infinity (which
* normally shouldn't happen).
*/
- ec_GFp_nistp_points_make_affine_internal(num,
- points,
- sizeof(smallfelem),
- tmp_smallfelems,
- (void (*)(void *))smallfelem_one,
- smallfelem_is_zero_int,
- (void (*)(void *, const void *))
- smallfelem_assign,
- (void (*)(void *, const void *))
- smallfelem_square_contract,
- (void (*)
- (void *, const void *,
- const void *))
- smallfelem_mul_contract,
- (void (*)(void *, const void *))
- smallfelem_inv_contract,
- /* nothing to contract */
- (void (*)(void *, const void *))
- smallfelem_assign);
+ ossl_ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(smallfelem),
+ tmp_smallfelems,
+ (void (*)(void *))smallfelem_one,
+ smallfelem_is_zero_int,
+ (void (*)(void *, const void *))
+ smallfelem_assign,
+ (void (*)(void *, const void *))
+ smallfelem_square_contract,
+ (void (*)
+ (void *, const void *,
+ const void *))
+ smallfelem_mul_contract,
+ (void (*)(void *, const void *))
+ smallfelem_inv_contract,
+ /* nothing to contract */
+ (void (*)(void *, const void *))
+ smallfelem_assign);
}
/*
* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
* values Result is stored in r (r can equal one of the inputs).
*/
-int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx)
+int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
{
int ret = 0;
int j;
@@ -2065,12 +2068,12 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
!smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
!smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
- generator, x, y, z,
- ctx))
+ if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group,
+ generator,
+ x, y, z, ctx))
goto err;
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
/* precomputation matches generator */
@@ -2097,7 +2100,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1));
if ((secrets == NULL) || (pre_comp == NULL)
|| (mixed && (tmp_smallfelems == NULL))) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -2129,7 +2132,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar,
@@ -2139,7 +2142,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */
@@ -2183,7 +2186,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
@@ -2207,10 +2210,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_contract(z_in, z_out);
if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
(!smallfelem_to_BN(z, z_in))) {
- ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+ ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z,
+ ctx);
err:
BN_CTX_end(ctx);
@@ -2221,22 +2225,29 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
return ret;
}
-int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
NISTP256_PRE_COMP *pre = NULL;
int i, j;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
EC_POINT *generator = NULL;
smallfelem tmp_smallfelems[32];
felem x_tmp, y_tmp, z_tmp;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
/* throw away old precomputation */
EC_pre_comp_free(group);
+
+#ifndef FIPS_MODULE
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -2354,13 +2365,14 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
EC_nistp256_pre_comp_free(pre);
return ret;
}
-int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
+int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
{
return HAVEPRECOMP(group, nistp256);
}
-#endif
diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c
index 08b32787293b..31a97d793742 100644
--- a/crypto/ec/ecp_nistp521.c
+++ b/crypto/ec/ecp_nistp521.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -24,6 +24,12 @@
*/
/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+/*
* A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
*
* OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
@@ -32,27 +38,22 @@
*/
#include <openssl/e_os2.h>
-#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-NON_EMPTY_TRANSLATION_UNIT
-#else
-# include <string.h>
-# include <openssl/err.h>
-# include "ec_local.h"
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_local.h"
-# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
- /* even with gcc, the typedef won't work for 32-bit platforms */
-typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
- * platforms */
-# else
-# error "Your compiler doesn't appear to support 128-bit integer types"
-# endif
+#include "internal/numbers.h"
+
+#ifndef INT128_MAX
+# error "Your compiler doesn't appear to support 128-bit integer types"
+#endif
typedef uint8_t u8;
typedef uint64_t u64;
/*
- * The underlying field. P521 operates over GF(2^521-1). We can serialise an
+ * The underlying field. P521 operates over GF(2^521-1). We can serialize an
* element of this field into 66 bytes where the most significant byte
* contains only a single bit. We call this an felem_bytearray.
*/
@@ -125,7 +126,7 @@ static const felem_bytearray nistp521_curve_params[5] = {
* A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
* 'largefelem' */
-# define NLIMBS 9
+#define NLIMBS 9
typedef uint64_t limb;
typedef limb limb_aX __attribute((__aligned__(1)));
@@ -153,7 +154,7 @@ static void bin66_to_felem(felem out, const u8 in[66])
}
/*
- * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
+ * felem_to_bin66 takes an felem and serializes into a little endian, 66 byte
* array. This assumes that the CPU is little-endian.
*/
static void felem_to_bin66(u8 out[66], const felem in)
@@ -177,12 +178,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
int num_bytes;
if (BN_is_negative(bn)) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
if (num_bytes < 0) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
bin66_to_felem(out, b_out);
@@ -400,7 +401,7 @@ static void felem_diff128(largefelem out, const largefelem in)
* On exit:
* out[i] < 17 * max(in[i]) * max(in[i])
*/
-static void felem_square(largefelem out, const felem in)
+static void felem_square_ref(largefelem out, const felem in)
{
felem inx2, inx4;
felem_scalar(inx2, in, 2);
@@ -484,7 +485,7 @@ static void felem_square(largefelem out, const felem in)
* On exit:
* out[i] < 17 * max(in1[i]) * max(in2[i])
*/
-static void felem_mul(largefelem out, const felem in1, const felem in2)
+static void felem_mul_ref(largefelem out, const felem in1, const felem in2)
{
felem in2x2;
felem_scalar(in2x2, in2, 2);
@@ -674,6 +675,57 @@ static void felem_reduce(felem out, const largefelem in)
*/
}
+#if defined(ECP_NISTP521_ASM)
+void felem_square_wrapper(largefelem out, const felem in);
+void felem_mul_wrapper(largefelem out, const felem in1, const felem in2);
+
+static void (*felem_square_p)(largefelem out, const felem in) =
+ felem_square_wrapper;
+static void (*felem_mul_p)(largefelem out, const felem in1, const felem in2) =
+ felem_mul_wrapper;
+
+void p521_felem_square(largefelem out, const felem in);
+void p521_felem_mul(largefelem out, const felem in1, const felem in2);
+
+# if defined(_ARCH_PPC64)
+# include "crypto/ppc_arch.h"
+# endif
+
+void felem_select(void)
+{
+# if defined(_ARCH_PPC64)
+ if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) {
+ felem_square_p = p521_felem_square;
+ felem_mul_p = p521_felem_mul;
+
+ return;
+ }
+# endif
+
+ /* Default */
+ felem_square_p = felem_square_ref;
+ felem_mul_p = felem_mul_ref;
+}
+
+void felem_square_wrapper(largefelem out, const felem in)
+{
+ felem_select();
+ felem_square_p(out, in);
+}
+
+void felem_mul_wrapper(largefelem out, const felem in1, const felem in2)
+{
+ felem_select();
+ felem_mul_p(out, in1, in2);
+}
+
+# define felem_square felem_square_p
+# define felem_mul felem_mul_p
+#else
+# define felem_square felem_square_ref
+# define felem_mul felem_mul_ref
+#endif
+
static void felem_square_reduce(felem out, const felem in)
{
largefelem tmp;
@@ -1266,8 +1318,8 @@ static void point_add(felem x3, felem y3, felem z3,
* This is obviously not constant-time but it will almost-never happen
* for ECDH / ECDSA. The case where it can happen is during scalar-mult
* where the intermediate value gets very close to the group order.
- * Since |ec_GFp_nistp_recode_scalar_bits| produces signed digits for
- * the scalar, it's possible for the intermediate value to be a small
+ * Since |ossl_ec_GFp_nistp_recode_scalar_bits| produces signed digits
+ * for the scalar, it's possible for the intermediate value to be a small
* negative multiple of the base point, and for the final signed digit
* to be the same value. We believe that this only occurs for the scalar
* 1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -1584,7 +1636,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
bits |= get_bit(scalars[num], i + 1) << 2;
bits |= get_bit(scalars[num], i) << 1;
bits |= get_bit(scalars[num], i - 1);
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+ ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
/*
* select the point to add or subtract, in constant time
@@ -1622,54 +1674,55 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_nistp521_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_nist_group_copy,
- ec_GFp_nistp521_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_nistp521_point_get_affine_coordinates,
+ ossl_ec_GFp_nistp521_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_nist_group_copy,
+ ossl_ec_GFp_nistp521_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_nistp521_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */ ,
0 /* point2oct */ ,
0 /* oct2point */ ,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- ec_GFp_nistp521_points_mul,
- ec_GFp_nistp521_precompute_mult,
- ec_GFp_nistp521_have_precompute_mult,
- ec_GFp_nist_field_mul,
- ec_GFp_nist_field_sqr,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_nistp521_points_mul,
+ ossl_ec_GFp_nistp521_precompute_mult,
+ ossl_ec_GFp_nistp521_have_precompute_mult,
+ ossl_ec_GFp_nist_field_mul,
+ ossl_ec_GFp_nist_field_sqr,
0 /* field_div */ ,
- ec_GFp_simple_field_inv,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
0, /* ladder_pre */
@@ -1690,7 +1743,7 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new(void)
NISTP521_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
@@ -1698,7 +1751,7 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new(void)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
@@ -1721,7 +1774,7 @@ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
return;
CRYPTO_DOWN_REF(&p->references, &i, p->lock);
- REF_PRINT_COUNT("EC_nistp521", x);
+ REF_PRINT_COUNT("EC_nistp521", p);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
@@ -1735,25 +1788,29 @@ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
* OPENSSL EC_METHOD FUNCTIONS
*/
-int ec_GFp_nistp521_group_init(EC_GROUP *group)
+int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group)
{
int ret;
- ret = ec_GFp_simple_group_init(group);
+ ret = ossl_ec_GFp_simple_group_init(group);
group->a_is_minus3 = 1;
return ret;
}
-int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
int ret = 0;
- BN_CTX *new_ctx = NULL;
BIGNUM *curve_p, *curve_a, *curve_b;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
curve_p = BN_CTX_get(ctx);
curve_a = BN_CTX_get(ctx);
@@ -1764,15 +1821,16 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
- ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
- EC_R_WRONG_CURVE_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
group->field_mod_func = BN_nist_mod_521;
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
@@ -1780,17 +1838,16 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
* Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
* (X/Z^2, Y/Z^3)
*/
-int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
felem z1, z2, x_in, y_in, x_out, y_out;
largefelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
@@ -1804,8 +1861,7 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(x_out, x_in);
if (x != NULL) {
if (!felem_to_BN(x, x_out)) {
- ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1816,8 +1872,7 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(y_out, y_in);
if (y != NULL) {
if (!felem_to_BN(y, y_out)) {
- ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
@@ -1832,36 +1887,36 @@ static void make_points_affine(size_t num, felem points[][3],
* Runs in constant time, unless an input is the point at infinity (which
* normally shouldn't happen).
*/
- ec_GFp_nistp_points_make_affine_internal(num,
- points,
- sizeof(felem),
- tmp_felems,
- (void (*)(void *))felem_one,
- felem_is_zero_int,
- (void (*)(void *, const void *))
- felem_assign,
- (void (*)(void *, const void *))
- felem_square_reduce, (void (*)
- (void *,
- const void
- *,
- const void
- *))
- felem_mul_reduce,
- (void (*)(void *, const void *))
- felem_inv,
- (void (*)(void *, const void *))
- felem_contract);
+ ossl_ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *))felem_one,
+ felem_is_zero_int,
+ (void (*)(void *, const void *))
+ felem_assign,
+ (void (*)(void *, const void *))
+ felem_square_reduce, (void (*)
+ (void *,
+ const void
+ *,
+ const void
+ *))
+ felem_mul_reduce,
+ (void (*)(void *, const void *))
+ felem_inv,
+ (void (*)(void *, const void *))
+ felem_contract);
}
/*
* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
* values Result is stored in r (r can equal one of the inputs).
*/
-int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx)
+int ossl_ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
{
int ret = 0;
int j;
@@ -1905,12 +1960,12 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!felem_to_BN(x, g_pre_comp[1][0]) ||
!felem_to_BN(y, g_pre_comp[1][1]) ||
!felem_to_BN(z, g_pre_comp[1][2])) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
- generator, x, y, z,
- ctx))
+ if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group,
+ generator,
+ x, y, z, ctx))
goto err;
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
/* precomputation matches generator */
@@ -1938,7 +1993,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1));
if ((secrets == NULL) || (pre_comp == NULL)
|| (mixed && (tmp_felems == NULL))) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1968,7 +2023,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar,
@@ -1978,7 +2033,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
secrets[i], sizeof(secrets[i]));
}
if (num_bytes < 0) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
/* precompute multiples */
@@ -2020,7 +2075,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
@@ -2045,10 +2100,11 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_contract(z_in, z_out);
if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
(!felem_to_BN(z, z_in))) {
- ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+ ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z,
+ ctx);
err:
BN_CTX_end(ctx);
@@ -2059,21 +2115,28 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
return ret;
}
-int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
NISTP521_PRE_COMP *pre = NULL;
int i, j;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
EC_POINT *generator = NULL;
felem tmp_felems[16];
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
/* throw away old precomputation */
EC_pre_comp_free(group);
+
+#ifndef FIPS_MODULE
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -2161,14 +2224,14 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
EC_nistp521_pre_comp_free(pre);
return ret;
}
-int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
+int ossl_ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
{
return HAVEPRECOMP(group, nistp521);
}
-
-#endif
diff --git a/crypto/ec/ecp_nistputil.c b/crypto/ec/ecp_nistputil.c
index 60e1325c340f..4e8c0e276769 100644
--- a/crypto/ec/ecp_nistputil.c
+++ b/crypto/ec/ecp_nistputil.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -23,17 +23,20 @@
* limitations under the License.
*/
+/*
+ * ECDSA 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_EC_NISTP_64_GCC_128
-NON_EMPTY_TRANSLATION_UNIT
-#else
/*
* Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
*/
-# include <stddef.h>
-# include "ec_local.h"
+#include <stddef.h>
+#include "ec_local.h"
/*
* Convert an array of points into affine coordinates. (If the point at
@@ -46,7 +49,8 @@ NON_EMPTY_TRANSLATION_UNIT
* of size 'felem_size'. tmp_felems needs to point to a temporary array of
* 'num'+1 field elements for storage of intermediate values.
*/
-void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+void
+ossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
size_t felem_size,
void *tmp_felems,
void (*felem_one) (void *out),
@@ -74,10 +78,10 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
{
int i = 0;
-# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
-# define X(I) (&((char *)point_array)[3*(I) * felem_size])
-# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
-# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
+#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
+#define X(I) (&((char *)point_array)[3*(I) * felem_size])
+#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
+#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
if (!felem_is_zero(Z(0)))
felem_assign(tmp_felem(0), Z(0));
@@ -206,8 +210,8 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
* b_-1, has to be b_4 b_3 b_2 b_1 b_0 0.
*
*/
-void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
- unsigned char *digit, unsigned char in)
+void ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+ unsigned char *digit, unsigned char in)
{
unsigned char s, d;
@@ -220,4 +224,3 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
*sign = s & 1;
*digit = d;
}
-#endif
diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c
index cfad3e15b0bf..d65f6984ded3 100644
--- a/crypto/ec/ecp_nistz256.c
+++ b/crypto/ec/ecp_nistz256.c
@@ -3,7 +3,7 @@
* Copyright (c) 2014, Intel Corporation. All Rights Reserved.
* Copyright (c) 2015, CloudFlare, Inc.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
@@ -18,6 +18,12 @@
* 256 Bit Primes"
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <string.h>
#include "internal/cryptlib.h"
@@ -631,7 +637,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group,
|| (p_str =
OPENSSL_malloc(num * 33 * sizeof(unsigned char))) == NULL
|| (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) {
- ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -648,7 +654,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group,
if ((mod = BN_CTX_get(ctx)) == NULL)
goto err;
if (!BN_nnmod(mod, scalar[i], group->order, ctx)) {
- ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
scalars[i] = mod;
@@ -676,8 +682,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group,
if (!ecp_nistz256_bignum_to_field_elem(temp[0].X, point[i]->X)
|| !ecp_nistz256_bignum_to_field_elem(temp[0].Y, point[i]->Y)
|| !ecp_nistz256_bignum_to_field_elem(temp[0].Z, point[i]->Z)) {
- ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL,
- EC_R_COORDINATES_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
@@ -828,7 +833,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
EC_pre_comp_free(group);
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
return 0;
}
@@ -844,7 +849,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
return 0;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
goto err;
}
@@ -856,7 +861,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
goto err;
if (BN_is_zero(order)) {
- ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNKNOWN_ORDER);
+ ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER);
goto err;
}
@@ -864,7 +869,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
if ((precomp_storage =
OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) {
- ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -891,12 +896,12 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
* It would be faster to use EC_POINTs_make_affine and
* make multiple points affine at the same time.
*/
- if (!EC_POINT_make_affine(group, P, ctx))
+ if (group->meth->make_affine == NULL
+ || !group->meth->make_affine(group, P, ctx))
goto err;
if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) ||
!ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) {
- ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE,
- EC_R_COORDINATES_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
ecp_nistz256_scatter_w7(preComputedTable[j], &temp, k);
@@ -969,7 +974,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
BIGNUM *tmp_scalar;
if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) {
- ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -979,7 +984,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
if (scalar) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_UNDEFINED_GENERATOR);
+ ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
@@ -1027,7 +1032,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
goto err;
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
- ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
scalar = tmp_scalar;
@@ -1119,13 +1124,13 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
*/
new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
if (new_scalars == NULL) {
- ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
if (new_points == NULL) {
- ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1180,14 +1185,14 @@ __owur static int ecp_nistz256_get_affine(const EC_GROUP *group,
BN_ULONG x_ret[P256_LIMBS], y_ret[P256_LIMBS];
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if (!ecp_nistz256_bignum_to_field_elem(point_x, point->X) ||
!ecp_nistz256_bignum_to_field_elem(point_y, point->Y) ||
!ecp_nistz256_bignum_to_field_elem(point_z, point->Z)) {
- ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_COORDINATES_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
return 0;
}
@@ -1222,7 +1227,7 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group)
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
- ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
@@ -1232,7 +1237,7 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group)
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
@@ -1255,7 +1260,7 @@ void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre)
return;
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
- REF_PRINT_COUNT("EC_nistz256", x);
+ REF_PRINT_COUNT("EC_nistz256", pre);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
@@ -1291,7 +1296,7 @@ void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG b[P256_LIMBS]);
void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS],
- int rep);
+ BN_ULONG rep);
static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
const BIGNUM *x, BN_CTX *ctx)
@@ -1321,7 +1326,7 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
* Catch allocation failure early.
*/
if (bn_wexpand(r, P256_LIMBS) == NULL) {
- ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -1330,14 +1335,14 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
if ((tmp = BN_CTX_get(ctx)) == NULL
|| !BN_nnmod(tmp, x, group->order, ctx)) {
- ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
x = tmp;
}
if (!ecp_nistz256_bignum_to_field_elem(t, x)) {
- ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, EC_R_COORDINATES_OUT_OF_RANGE);
+ ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
@@ -1467,52 +1472,53 @@ const EC_METHOD *EC_GFp_nistz256_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_mont_group_init,
- ec_GFp_mont_group_finish,
- ec_GFp_mont_group_clear_finish,
- ec_GFp_mont_group_copy,
- ec_GFp_mont_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_mont_group_init,
+ ossl_ec_GFp_mont_group_finish,
+ ossl_ec_GFp_mont_group_clear_finish,
+ ossl_ec_GFp_mont_group_copy,
+ ossl_ec_GFp_mont_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
ecp_nistz256_get_affine,
0, 0, 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
ecp_nistz256_points_mul, /* mul */
ecp_nistz256_mult_precompute, /* precompute_mult */
ecp_nistz256_window_have_precompute_mult, /* have_precompute_mult */
- ec_GFp_mont_field_mul,
- ec_GFp_mont_field_sqr,
+ ossl_ec_GFp_mont_field_mul,
+ ossl_ec_GFp_mont_field_sqr,
0, /* field_div */
- ec_GFp_mont_field_inv,
- ec_GFp_mont_field_encode,
- ec_GFp_mont_field_decode,
- ec_GFp_mont_field_set_to_one,
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_GFp_mont_field_inv,
+ ossl_ec_GFp_mont_field_encode,
+ ossl_ec_GFp_mont_field_decode,
+ ossl_ec_GFp_mont_field_set_to_one,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
ecp_nistz256_inv_mod_ord, /* can be #define-d NULL */
0, /* blind_coordinates */
0, /* ladder_pre */
diff --git a/crypto/ec/ecp_nistz256_table.c b/crypto/ec/ecp_nistz256_table.c
index 3f5625c6c5eb..71430d4b8142 100644
--- a/crypto/ec/ecp_nistz256_table.c
+++ b/crypto/ec/ecp_nistz256_table.c
@@ -1,7 +1,7 @@
/*
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
diff --git a/crypto/ec/ecp_oct.c b/crypto/ec/ecp_oct.c
index 9460763256fd..68943e521e8a 100644
--- a/crypto/ec/ecp_oct.c
+++ b/crypto/ec/ecp_oct.c
@@ -1,32 +1,35 @@
/*
- * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
#include <openssl/symhacks.h>
#include "ec_local.h"
-int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
- EC_POINT *point,
- const BIGNUM *x_, int y_bit,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x_, int y_bit,
+ BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *tmp1, *tmp2, *x, *y;
int ret = 0;
- /* clear error queue */
- ERR_clear_error();
-
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -98,19 +101,24 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
goto err;
}
+ ERR_set_mark();
if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
+#ifndef FIPS_MODULE
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_BN
&& ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
- ERR_clear_error();
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
- EC_R_INVALID_COMPRESSED_POINT);
+ ERR_pop_to_mark();
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT);
} else
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
- ERR_R_BN_LIB);
+#endif
+ {
+ ERR_clear_last_mark();
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ }
goto err;
}
+ ERR_clear_last_mark();
if (y_bit != BN_is_odd(y)) {
if (BN_is_zero(y)) {
@@ -121,22 +129,19 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
goto err;
if (kron == 1)
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
- EC_R_INVALID_COMPRESSION_BIT);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT);
else
/*
* BN_mod_sqrt() should have caught this error (not a square)
*/
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
- EC_R_INVALID_COMPRESSED_POINT);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT);
goto err;
}
if (!BN_usub(y, group->field, y))
goto err;
}
if (y_bit != BN_is_odd(y)) {
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
- ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -151,9 +156,9 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
return ret;
}
-size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
- point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
+size_t ossl_ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
{
size_t ret;
BN_CTX *new_ctx = NULL;
@@ -164,7 +169,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
if ((form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM);
goto err;
}
@@ -172,7 +177,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
@@ -189,12 +194,12 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -219,7 +224,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
skip = field_len - BN_num_bytes(x);
if (skip > field_len) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
@@ -229,7 +234,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -237,7 +242,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|| form == POINT_CONVERSION_HYBRID) {
skip = field_len - BN_num_bytes(y);
if (skip > field_len) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
@@ -249,7 +254,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
}
if (i != ret) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
@@ -266,8 +271,9 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
return 0;
}
-int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
+int ossl_ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len,
+ BN_CTX *ctx)
{
point_conversion_form_t form;
int y_bit;
@@ -277,7 +283,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
int ret = 0;
if (len == 0) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
form = buf[0];
@@ -286,17 +292,17 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0) {
if (len != 1) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -309,12 +315,12 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
if (len != enc_len) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -328,7 +334,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!BN_bin2bn(buf + 1, field_len, x))
goto err;
if (BN_ucmp(x, group->field) >= 0) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -339,12 +345,12 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
goto err;
if (BN_ucmp(y, group->field) >= 0) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID) {
if (y_bit != BN_is_odd(y)) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
goto err;
}
}
diff --git a/crypto/ec/ecp_ppc.c b/crypto/ec/ecp_ppc.c
new file mode 100644
index 000000000000..b2b9f772b87b
--- /dev/null
+++ b/crypto/ec/ecp_ppc.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009-2021 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 "internal/cryptlib.h"
+#include "crypto/ppc_arch.h"
+#include "ec_local.h"
+
+void ecp_nistz256_mul_mont(unsigned long res[4], const unsigned long a[4],
+ const unsigned long b[4]);
+
+void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]);
+void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4])
+{
+ static const unsigned long RR[] = { 0x0000000000000003U,
+ 0xfffffffbffffffffU,
+ 0xfffffffffffffffeU,
+ 0x00000004fffffffdU };
+
+ ecp_nistz256_mul_mont(res, in, RR);
+}
+
+void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]);
+void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4])
+{
+ static const unsigned long one[] = { 1, 0, 0, 0 };
+
+ ecp_nistz256_mul_mont(res, in, one);
+}
diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c
new file mode 100644
index 000000000000..0c10196ea34e
--- /dev/null
+++ b/crypto/ec/ecp_s390x_nistp.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2019-2022 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
+ */
+
+/*
+ * EC_METHOD low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include "ec_local.h"
+#include "s390x_arch.h"
+
+/* Size of parameter blocks */
+#define S390X_SIZE_PARAM 4096
+
+/* Size of fields in parameter blocks */
+#define S390X_SIZE_P256 32
+#define S390X_SIZE_P384 48
+#define S390X_SIZE_P521 80
+
+/* Offsets of fields in PCC parameter blocks */
+#define S390X_OFF_RES_X(n) (0 * n)
+#define S390X_OFF_RES_Y(n) (1 * n)
+#define S390X_OFF_SRC_X(n) (2 * n)
+#define S390X_OFF_SRC_Y(n) (3 * n)
+#define S390X_OFF_SCALAR(n) (4 * n)
+
+/* Offsets of fields in KDSA parameter blocks */
+#define S390X_OFF_R(n) (0 * n)
+#define S390X_OFF_S(n) (1 * n)
+#define S390X_OFF_H(n) (2 * n)
+#define S390X_OFF_K(n) (3 * n)
+#define S390X_OFF_X(n) (3 * n)
+#define S390X_OFF_RN(n) (4 * n)
+#define S390X_OFF_Y(n) (4 * n)
+
+static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[],
+ BN_CTX *ctx, unsigned int fc, int len)
+{
+ unsigned char param[S390X_SIZE_PARAM];
+ BIGNUM *x, *y;
+ const EC_POINT *point_ptr = NULL;
+ const BIGNUM *scalar_ptr = NULL;
+ BN_CTX *new_ctx = NULL;
+ int rc = -1;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (x == NULL || y == NULL) {
+ rc = 0;
+ goto ret;
+ }
+
+ /*
+ * Use PCC for EC keygen and ECDH key derivation:
+ * scalar * generator and scalar * peer public key,
+ * scalar in [0,order).
+ */
+ if ((scalar != NULL && num == 0 && BN_is_negative(scalar) == 0)
+ || (scalar == NULL && num == 1 && BN_is_negative(scalars[0]) == 0)) {
+
+ if (num == 0) {
+ point_ptr = EC_GROUP_get0_generator(group);
+ scalar_ptr = scalar;
+ } else {
+ point_ptr = points[0];
+ scalar_ptr = scalars[0];
+ }
+
+ if (EC_POINT_is_at_infinity(group, point_ptr) == 1
+ || BN_is_zero(scalar_ptr)) {
+ rc = EC_POINT_set_to_infinity(group, r);
+ goto ret;
+ }
+
+ memset(&param, 0, sizeof(param));
+
+ if (group->meth->point_get_affine_coordinates(group, point_ptr,
+ x, y, ctx) != 1
+ || BN_bn2binpad(x, param + S390X_OFF_SRC_X(len), len) == -1
+ || BN_bn2binpad(y, param + S390X_OFF_SRC_Y(len), len) == -1
+ || BN_bn2binpad(scalar_ptr,
+ param + S390X_OFF_SCALAR(len), len) == -1
+ || s390x_pcc(fc, param) != 0
+ || BN_bin2bn(param + S390X_OFF_RES_X(len), len, x) == NULL
+ || BN_bin2bn(param + S390X_OFF_RES_Y(len), len, y) == NULL
+ || group->meth->point_set_affine_coordinates(group, r,
+ x, y, ctx) != 1)
+ goto ret;
+
+ rc = 1;
+ }
+
+ret:
+ /* Otherwise use default. */
+ if (rc == -1)
+ rc = ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ OPENSSL_cleanse(param, sizeof(param));
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return rc;
+}
+
+static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
+ int dgstlen,
+ const BIGNUM *kinv,
+ const BIGNUM *r,
+ EC_KEY *eckey,
+ unsigned int fc, int len)
+{
+ unsigned char param[S390X_SIZE_PARAM];
+ int ok = 0;
+ BIGNUM *k;
+ ECDSA_SIG *sig;
+ const EC_GROUP *group;
+ const BIGNUM *privkey;
+ int off;
+
+ group = EC_KEY_get0_group(eckey);
+ privkey = EC_KEY_get0_private_key(eckey);
+ if (group == NULL || privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
+ return NULL;
+ }
+
+ if (!EC_KEY_can_sign(eckey)) {
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ return NULL;
+ }
+
+ k = BN_secure_new();
+ sig = ECDSA_SIG_new();
+ if (k == NULL || sig == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ sig->r = BN_new();
+ sig->s = BN_new();
+ if (sig->r == NULL || sig->s == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ memset(param, 0, sizeof(param));
+ off = len - (dgstlen > len ? len : dgstlen);
+ memcpy(param + S390X_OFF_H(len) + off, dgst, len - off);
+
+ if (BN_bn2binpad(privkey, param + S390X_OFF_K(len), len) == -1) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ if (r == NULL || kinv == NULL) {
+ if (len < 0) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_LENGTH);
+ goto ret;
+ }
+ /*
+ * 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_ex(eckey->libctx, param + S390X_OFF_RN(len),
+ (size_t)len, 0) != 1) {
+ ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+ goto ret;
+ }
+ } else {
+ /* Reconstruct k = (k^-1)^-1. */
+ if (ossl_ec_group_do_inverse_ord(group, k, kinv, NULL) == 0
+ || BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto ret;
+ }
+ /* Turns KDSA internal nonce-generation off. */
+ fc |= S390X_KDSA_D;
+ }
+
+ if (s390x_kdsa(fc, param, NULL, 0) != 0) {
+ ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB);
+ goto ret;
+ }
+
+ if (BN_bin2bn(param + S390X_OFF_R(len), len, sig->r) == NULL
+ || BN_bin2bn(param + S390X_OFF_S(len), len, sig->s) == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ ok = 1;
+ret:
+ OPENSSL_cleanse(param, sizeof(param));
+ if (ok != 1) {
+ ECDSA_SIG_free(sig);
+ sig = NULL;
+ }
+ BN_clear_free(k);
+ return sig;
+}
+
+static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen,
+ const ECDSA_SIG *sig, EC_KEY *eckey,
+ unsigned int fc, int len)
+{
+ unsigned char param[S390X_SIZE_PARAM];
+ int rc = -1;
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ const EC_GROUP *group;
+ const EC_POINT *pubkey;
+ int off;
+
+ group = EC_KEY_get0_group(eckey);
+ pubkey = EC_KEY_get0_public_key(eckey);
+ if (eckey == NULL || group == NULL || pubkey == NULL || sig == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ if (!EC_KEY_can_sign(eckey)) {
+ ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ return -1;
+ }
+
+ ctx = BN_CTX_new_ex(group->libctx);
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (x == NULL || y == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ memset(param, 0, sizeof(param));
+ off = len - (dgstlen > len ? len : dgstlen);
+ memcpy(param + S390X_OFF_H(len) + off, dgst, len - off);
+
+ if (group->meth->point_get_affine_coordinates(group, pubkey,
+ x, y, ctx) != 1
+ || BN_bn2binpad(sig->r, param + S390X_OFF_R(len), len) == -1
+ || BN_bn2binpad(sig->s, param + S390X_OFF_S(len), len) == -1
+ || BN_bn2binpad(x, param + S390X_OFF_X(len), len) == -1
+ || BN_bn2binpad(y, param + S390X_OFF_Y(len), len) == -1) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ rc = s390x_kdsa(fc, param, NULL, 0) == 0 ? 1 : 0;
+ret:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return rc;
+}
+
+#define EC_GFP_S390X_NISTP_METHOD(bits) \
+ \
+static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \
+ EC_POINT *r, \
+ const BIGNUM *scalar, \
+ size_t num, \
+ const EC_POINT *points[], \
+ const BIGNUM *scalars[], \
+ BN_CTX *ctx) \
+{ \
+ return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \
+ scalars, ctx, \
+ S390X_SCALAR_MULTIPLY_P##bits, \
+ S390X_SIZE_P##bits); \
+} \
+ \
+static ECDSA_SIG *ecdsa_s390x_nistp##bits##_sign_sig(const unsigned \
+ char *dgst, \
+ int dgstlen, \
+ const BIGNUM *kinv,\
+ const BIGNUM *r, \
+ EC_KEY *eckey) \
+{ \
+ return ecdsa_s390x_nistp_sign_sig(dgst, dgstlen, kinv, r, eckey, \
+ S390X_ECDSA_SIGN_P##bits, \
+ S390X_SIZE_P##bits); \
+} \
+ \
+static int ecdsa_s390x_nistp##bits##_verify_sig(const \
+ unsigned char *dgst, \
+ int dgstlen, \
+ const ECDSA_SIG *sig, \
+ EC_KEY *eckey) \
+{ \
+ return ecdsa_s390x_nistp_verify_sig(dgst, dgstlen, sig, eckey, \
+ S390X_ECDSA_VERIFY_P##bits, \
+ S390X_SIZE_P##bits); \
+} \
+ \
+const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \
+{ \
+ static const EC_METHOD EC_GFp_s390x_nistp##bits##_meth = { \
+ EC_FLAGS_DEFAULT_OCT, \
+ NID_X9_62_prime_field, \
+ ossl_ec_GFp_simple_group_init, \
+ ossl_ec_GFp_simple_group_finish, \
+ ossl_ec_GFp_simple_group_clear_finish, \
+ ossl_ec_GFp_simple_group_copy, \
+ ossl_ec_GFp_simple_group_set_curve, \
+ ossl_ec_GFp_simple_group_get_curve, \
+ ossl_ec_GFp_simple_group_get_degree, \
+ ossl_ec_group_simple_order_bits, \
+ ossl_ec_GFp_simple_group_check_discriminant, \
+ ossl_ec_GFp_simple_point_init, \
+ ossl_ec_GFp_simple_point_finish, \
+ ossl_ec_GFp_simple_point_clear_finish, \
+ ossl_ec_GFp_simple_point_copy, \
+ ossl_ec_GFp_simple_point_set_to_infinity, \
+ ossl_ec_GFp_simple_point_set_affine_coordinates, \
+ ossl_ec_GFp_simple_point_get_affine_coordinates, \
+ NULL, /* point_set_compressed_coordinates */ \
+ NULL, /* point2oct */ \
+ NULL, /* oct2point */ \
+ ossl_ec_GFp_simple_add, \
+ ossl_ec_GFp_simple_dbl, \
+ ossl_ec_GFp_simple_invert, \
+ ossl_ec_GFp_simple_is_at_infinity, \
+ ossl_ec_GFp_simple_is_on_curve, \
+ ossl_ec_GFp_simple_cmp, \
+ ossl_ec_GFp_simple_make_affine, \
+ ossl_ec_GFp_simple_points_make_affine, \
+ ec_GFp_s390x_nistp##bits##_mul, \
+ NULL, /* precompute_mult */ \
+ NULL, /* have_precompute_mult */ \
+ ossl_ec_GFp_simple_field_mul, \
+ ossl_ec_GFp_simple_field_sqr, \
+ NULL, /* field_div */ \
+ ossl_ec_GFp_simple_field_inv, \
+ NULL, /* field_encode */ \
+ NULL, /* field_decode */ \
+ NULL, /* field_set_to_one */ \
+ ossl_ec_key_simple_priv2oct, \
+ ossl_ec_key_simple_oct2priv, \
+ NULL, /* set_private */ \
+ ossl_ec_key_simple_generate_key, \
+ ossl_ec_key_simple_check_key, \
+ ossl_ec_key_simple_generate_public_key, \
+ NULL, /* keycopy */ \
+ NULL, /* keyfinish */ \
+ ossl_ecdh_simple_compute_key, \
+ ossl_ecdsa_simple_sign_setup, \
+ ecdsa_s390x_nistp##bits##_sign_sig, \
+ ecdsa_s390x_nistp##bits##_verify_sig, \
+ NULL, /* field_inverse_mod_ord */ \
+ ossl_ec_GFp_simple_blind_coordinates, \
+ ossl_ec_GFp_simple_ladder_pre, \
+ ossl_ec_GFp_simple_ladder_step, \
+ ossl_ec_GFp_simple_ladder_post \
+ }; \
+ static const EC_METHOD *ret; \
+ \
+ if ((OPENSSL_s390xcap_P.pcc[1] \
+ & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \
+ && (OPENSSL_s390xcap_P.kdsa[0] \
+ & S390X_CAPBIT(S390X_ECDSA_VERIFY_P##bits)) \
+ && (OPENSSL_s390xcap_P.kdsa[0] \
+ & S390X_CAPBIT(S390X_ECDSA_SIGN_P##bits))) \
+ ret = &EC_GFp_s390x_nistp##bits##_meth; \
+ else \
+ ret = EC_GFp_mont_method(); \
+ \
+ return ret; \
+}
+
+EC_GFP_S390X_NISTP_METHOD(256)
+EC_GFP_S390X_NISTP_METHOD(384)
+EC_GFP_S390X_NISTP_METHOD(521)
diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c
index b3110ec89dbe..bde8cad34641 100644
--- a/crypto/ec/ecp_smpl.c
+++ b/crypto/ec/ecp_smpl.c
@@ -1,13 +1,19 @@
/*
- * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/err.h>
#include <openssl/symhacks.h>
@@ -18,57 +24,58 @@ const EC_METHOD *EC_GFp_simple_method(void)
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_simple_group_copy,
- ec_GFp_simple_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
+ ossl_ec_GFp_simple_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_simple_group_copy,
+ ossl_ec_GFp_simple_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_simple_point_get_affine_coordinates,
0, 0, 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
0 /* mul */ ,
0 /* precompute_mult */ ,
0 /* have_precompute_mult */ ,
- ec_GFp_simple_field_mul,
- ec_GFp_simple_field_sqr,
+ ossl_ec_GFp_simple_field_mul,
+ ossl_ec_GFp_simple_field_sqr,
0 /* field_div */ ,
- ec_GFp_simple_field_inv,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key,
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
0, /* field_inverse_mod_ord */
- ec_GFp_simple_blind_coordinates,
- ec_GFp_simple_ladder_pre,
- ec_GFp_simple_ladder_step,
- ec_GFp_simple_ladder_post
+ ossl_ec_GFp_simple_blind_coordinates,
+ ossl_ec_GFp_simple_ladder_pre,
+ ossl_ec_GFp_simple_ladder_step,
+ ossl_ec_GFp_simple_ladder_post
};
return &ret;
@@ -88,7 +95,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
* representation (i.e. 'encoding' means multiplying by some factor R).
*/
-int ec_GFp_simple_group_init(EC_GROUP *group)
+int ossl_ec_GFp_simple_group_init(EC_GROUP *group)
{
group->field = BN_new();
group->a = BN_new();
@@ -103,21 +110,21 @@ int ec_GFp_simple_group_init(EC_GROUP *group)
return 1;
}
-void ec_GFp_simple_group_finish(EC_GROUP *group)
+void ossl_ec_GFp_simple_group_finish(EC_GROUP *group)
{
BN_free(group->field);
BN_free(group->a);
BN_free(group->b);
}
-void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
+void ossl_ec_GFp_simple_group_clear_finish(EC_GROUP *group)
{
BN_clear_free(group->field);
BN_clear_free(group->a);
BN_clear_free(group->b);
}
-int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+int ossl_ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
if (!BN_copy(dest->field, src->field))
return 0;
@@ -131,9 +138,9 @@ int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
return 1;
}
-int ec_GFp_simple_group_set_curve(EC_GROUP *group,
- const BIGNUM *p, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_simple_group_set_curve(EC_GROUP *group,
+ const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
@@ -141,12 +148,12 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
/* p must be a prime > 3 */
if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
- ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
return 0;
}
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -190,8 +197,8 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
return ret;
}
-int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
- BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
+ BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
@@ -204,7 +211,7 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
if (a != NULL || b != NULL) {
if (group->meth->field_decode) {
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -235,12 +242,13 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
return ret;
}
-int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
+int ossl_ec_GFp_simple_group_get_degree(const EC_GROUP *group)
{
return BN_num_bits(group->field);
}
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *group,
+ BN_CTX *ctx)
{
int ret = 0;
BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
@@ -248,10 +256,9 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
BN_CTX *new_ctx = NULL;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL) {
- ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
- ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -312,7 +319,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
return ret;
}
-int ec_GFp_simple_point_init(EC_POINT *point)
+int ossl_ec_GFp_simple_point_init(EC_POINT *point)
{
point->X = BN_new();
point->Y = BN_new();
@@ -328,14 +335,14 @@ int ec_GFp_simple_point_init(EC_POINT *point)
return 1;
}
-void ec_GFp_simple_point_finish(EC_POINT *point)
+void ossl_ec_GFp_simple_point_finish(EC_POINT *point)
{
BN_free(point->X);
BN_free(point->Y);
BN_free(point->Z);
}
-void ec_GFp_simple_point_clear_finish(EC_POINT *point)
+void ossl_ec_GFp_simple_point_clear_finish(EC_POINT *point)
{
BN_clear_free(point->X);
BN_clear_free(point->Y);
@@ -343,7 +350,7 @@ void ec_GFp_simple_point_clear_finish(EC_POINT *point)
point->Z_is_one = 0;
}
-int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+int ossl_ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
{
if (!BN_copy(dest->X, src->X))
return 0;
@@ -357,26 +364,26 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
return 1;
}
-int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
- EC_POINT *point)
+int ossl_ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
+ EC_POINT *point)
{
point->Z_is_one = 0;
BN_zero(point->Z);
return 1;
}
-int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
- EC_POINT *point,
- const BIGNUM *x,
- const BIGNUM *y,
- const BIGNUM *z,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x,
+ const BIGNUM *y,
+ const BIGNUM *z,
+ BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
int ret = 0;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -425,17 +432,17 @@ int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
return ret;
}
-int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BIGNUM *z, BN_CTX *ctx)
+int ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BIGNUM *z, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
int ret = 0;
if (group->meth->field_decode != 0) {
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -474,17 +481,16 @@ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
return ret;
}
-int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
- EC_POINT *point,
- const BIGNUM *x,
- const BIGNUM *y, BN_CTX *ctx)
+int ossl_ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *ctx)
{
if (x == NULL || y == NULL) {
/*
* unlike for projective coordinates, we do not tolerate this
*/
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
- ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -492,10 +498,10 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
BN_value_one(), ctx);
}
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *Z, *Z_1, *Z_2, *Z_3;
@@ -503,13 +509,12 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -554,8 +559,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
}
} else {
if (!group->meth->field_inv(group, Z_1, Z_, ctx)) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
@@ -606,8 +610,8 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
return ret;
}
-int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *ctx)
+int ossl_ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
{
int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
const BIGNUM *, BN_CTX *);
@@ -629,7 +633,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
p = group->field;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -791,8 +795,8 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
return ret;
}
-int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *ctx)
{
int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
const BIGNUM *, BN_CTX *);
@@ -813,7 +817,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
p = group->field;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -933,7 +937,8 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
return ret;
}
-int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+int ossl_ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point,
+ BN_CTX *ctx)
{
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
/* point is its own inverse */
@@ -942,13 +947,14 @@ int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
return BN_usub(point->Y, group->field, point->Y);
}
-int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+int ossl_ec_GFp_simple_is_at_infinity(const EC_GROUP *group,
+ const EC_POINT *point)
{
return BN_is_zero(point->Z);
}
-int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
{
int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
const BIGNUM *, BN_CTX *);
@@ -966,7 +972,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
p = group->field;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return -1;
}
@@ -1050,8 +1056,8 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
return ret;
}
-int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *ctx)
+int ossl_ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
{
/*-
* return values:
@@ -1083,7 +1089,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
field_sqr = group->meth->field_sqr;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return -1;
}
@@ -1158,8 +1164,8 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
return ret;
}
-int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
+ BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
@@ -1169,7 +1175,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
return 1;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -1185,7 +1191,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
goto err;
if (!point->Z_is_one) {
- ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1197,8 +1203,8 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
return ret;
}
-int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
- EC_POINT *points[], BN_CTX *ctx)
+int ossl_ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *tmp, *tmp_Z;
@@ -1210,7 +1216,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
return 1;
if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
+ ctx = new_ctx = BN_CTX_new_ex(group->libctx);
if (ctx == NULL)
return 0;
}
@@ -1266,7 +1272,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
*/
if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) {
- ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
if (group->meth->field_encode != 0) {
@@ -1356,14 +1362,14 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
return ret;
}
-int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *ctx)
+int ossl_ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
{
return BN_mod_mul(r, a, b, group->field, ctx);
}
-int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
{
return BN_mod_sqr(r, a, group->field, ctx);
}
@@ -1374,14 +1380,15 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
* Since we don't have a Mont structure here, SCA hardening is with blinding.
* NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.)
*/
-int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
{
BIGNUM *e = NULL;
BN_CTX *new_ctx = NULL;
int ret = 0;
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
+ if (ctx == NULL
+ && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL)
return 0;
BN_CTX_start(ctx);
@@ -1389,7 +1396,7 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
goto err;
do {
- if (!BN_priv_rand_range(e, group->field))
+ if (!BN_priv_rand_range_ex(e, group->field, 0, ctx))
goto err;
} while (BN_is_zero(e));
@@ -1398,7 +1405,7 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
goto err;
/* r := 1/(a * e) */
if (!BN_mod_inverse(r, r, group->field, ctx)) {
- ECerr(EC_F_EC_GFP_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
+ ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT);
goto err;
}
/* r := e/(a * e) = 1/a */
@@ -1420,8 +1427,8 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
* lambda = [1,group->field)
*
*/
-int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
- BN_CTX *ctx)
+int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+ BN_CTX *ctx)
{
int ret = 0;
BIGNUM *lambda = NULL;
@@ -1431,7 +1438,7 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
lambda = BN_CTX_get(ctx);
temp = BN_CTX_get(ctx);
if (temp == NULL) {
- ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -1442,7 +1449,7 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
*/
do {
ERR_set_mark();
- ret = BN_priv_rand_range(lambda, group->field);
+ ret = BN_priv_rand_range_ex(lambda, group->field, 0, ctx);
ERR_pop_to_mark();
if (ret == 0) {
ret = 1;
@@ -1483,9 +1490,9 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
* Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z)
* for any non-zero \lambda that holds for projective (homogeneous) coords.
*/
-int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx)
+int ossl_ec_GFp_simple_ladder_pre(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx)
{
BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
@@ -1512,13 +1519,13 @@ int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
/* make sure lambda (r->Y here for storage) is not zero */
do {
- if (!BN_priv_rand_range(r->Y, group->field))
+ if (!BN_priv_rand_range_ex(r->Y, group->field, 0, ctx))
return 0;
} while (BN_is_zero(r->Y));
/* make sure lambda (s->Z here for storage) is not zero */
do {
- if (!BN_priv_rand_range(s->Z, group->field))
+ if (!BN_priv_rand_range_ex(s->Z, group->field, 0, ctx))
return 0;
} while (BN_is_zero(s->Z));
@@ -1553,9 +1560,9 @@ int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
* attacks", as described at
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4
*/
-int ec_GFp_simple_ladder_step(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx)
+int ossl_ec_GFp_simple_ladder_step(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
@@ -1641,9 +1648,9 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
* - Y1==0 implies p has order 2, so either r or s are infinity and handled by
* one of the BN_is_zero(...) branches.
*/
-int ec_GFp_simple_ladder_post(const EC_GROUP *group,
- EC_POINT *r, EC_POINT *s,
- EC_POINT *p, BN_CTX *ctx)
+int ossl_ec_GFp_simple_ladder_post(const EC_GROUP *group,
+ EC_POINT *r, EC_POINT *s,
+ EC_POINT *p, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c
new file mode 100644
index 000000000000..e42767d6bf0f
--- /dev/null
+++ b/crypto/ec/ecx_backend.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2020-2024 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/core_names.h>
+#include <openssl/params.h>
+#include <openssl/ec.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#ifndef FIPS_MODULE
+# include <openssl/x509.h>
+#endif
+#include "crypto/ecx.h"
+#include "ecx_backend.h"
+
+/*
+ * The intention with the "backend" source file is to offer backend support
+ * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
+ * implementations alike.
+ */
+
+int ossl_ecx_public_from_private(ECX_KEY *key)
+{
+ switch (key->type) {
+ case ECX_KEY_TYPE_X25519:
+ ossl_x25519_public_from_private(key->pubkey, key->privkey);
+ break;
+ case ECX_KEY_TYPE_ED25519:
+ if (!ossl_ed25519_public_from_private(key->libctx, key->pubkey,
+ key->privkey, key->propq)) {
+ ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY);
+ return 0;
+ }
+ break;
+ case ECX_KEY_TYPE_X448:
+ ossl_x448_public_from_private(key->pubkey, key->privkey);
+ break;
+ case ECX_KEY_TYPE_ED448:
+ if (!ossl_ed448_public_from_private(key->libctx, key->pubkey,
+ key->privkey, key->propq)) {
+ ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY);
+ return 0;
+ }
+ break;
+ }
+ return 1;
+}
+
+int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
+ int include_private)
+{
+ size_t privkeylen = 0, pubkeylen = 0;
+ const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
+ unsigned char *pubkey;
+
+ if (ecx == NULL)
+ return 0;
+
+ param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
+ if (include_private)
+ param_priv_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+
+ if (param_pub_key == NULL && param_priv_key == NULL)
+ return 0;
+
+ if (param_priv_key != NULL) {
+ if (!OSSL_PARAM_get_octet_string(param_priv_key,
+ (void **)&ecx->privkey, ecx->keylen,
+ &privkeylen))
+ return 0;
+ if (privkeylen != ecx->keylen) {
+ /*
+ * Invalid key length. We will clear what we've received now. We
+ * can't leave it to ossl_ecx_key_free() because that will call
+ * OPENSSL_secure_clear_free() and assume the correct key length
+ */
+ OPENSSL_secure_clear_free(ecx->privkey, privkeylen);
+ ecx->privkey = NULL;
+ return 0;
+ }
+ }
+
+
+ pubkey = ecx->pubkey;
+ if (param_pub_key != NULL
+ && !OSSL_PARAM_get_octet_string(param_pub_key,
+ (void **)&pubkey,
+ sizeof(ecx->pubkey), &pubkeylen))
+ return 0;
+
+ if ((param_pub_key != NULL && pubkeylen != ecx->keylen))
+ return 0;
+
+ if (param_pub_key == NULL && !ossl_ecx_public_from_private(ecx))
+ return 0;
+
+ ecx->haspubkey = 1;
+
+ return 1;
+}
+
+ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection)
+{
+ ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ ret->libctx = key->libctx;
+ ret->haspubkey = 0;
+ ret->keylen = key->keylen;
+ ret->type = key->type;
+ ret->references = 1;
+
+ if (key->propq != NULL) {
+ ret->propq = OPENSSL_strdup(key->propq);
+ if (ret->propq == NULL)
+ goto err;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
+ && key->haspubkey == 1) {
+ memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey));
+ ret->haspubkey = 1;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+ && key->privkey != NULL) {
+ if (ossl_ecx_key_allocate_privkey(ret) == NULL)
+ goto err;
+ memcpy(ret->privkey, key->privkey, ret->keylen);
+ }
+
+ return ret;
+
+err:
+ ossl_ecx_key_free(ret);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
+
+#ifndef FIPS_MODULE
+ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg,
+ const unsigned char *p, int plen,
+ int id, ecx_key_op_t op,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ ECX_KEY *key = NULL;
+ unsigned char *privkey, *pubkey;
+
+ if (op != KEY_OP_KEYGEN) {
+ if (palg != NULL) {
+ int ptype;
+
+ /* Algorithm parameters must be absent */
+ X509_ALGOR_get0(NULL, &ptype, NULL, palg);
+ if (ptype != V_ASN1_UNDEF) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if (id == EVP_PKEY_NONE)
+ id = OBJ_obj2nid(palg->algorithm);
+ else if (id != OBJ_obj2nid(palg->algorithm)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ }
+
+ if (p == NULL || id == EVP_PKEY_NONE || plen != KEYLENID(id)) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ }
+
+ key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq);
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ pubkey = key->pubkey;
+
+ if (op == KEY_OP_PUBLIC) {
+ memcpy(pubkey, p, plen);
+ } else {
+ privkey = ossl_ecx_key_allocate_privkey(key);
+ if (privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (op == KEY_OP_KEYGEN) {
+ if (id != EVP_PKEY_NONE) {
+ if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id), 0) <= 0)
+ goto err;
+ if (id == EVP_PKEY_X25519) {
+ privkey[0] &= 248;
+ privkey[X25519_KEYLEN - 1] &= 127;
+ privkey[X25519_KEYLEN - 1] |= 64;
+ } else if (id == EVP_PKEY_X448) {
+ privkey[0] &= 252;
+ privkey[X448_KEYLEN - 1] |= 128;
+ }
+ }
+ } else {
+ memcpy(privkey, p, KEYLENID(id));
+ }
+ if (!ossl_ecx_public_from_private(key)) {
+ ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY);
+ goto err;
+ }
+ }
+
+ return key;
+ err:
+ ossl_ecx_key_free(key);
+ return NULL;
+}
+
+ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ ECX_KEY *ecx = NULL;
+ const unsigned char *p;
+ int plen;
+ ASN1_OCTET_STRING *oct = NULL;
+ const X509_ALGOR *palg;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf))
+ return 0;
+
+ oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
+ if (oct == NULL) {
+ p = NULL;
+ plen = 0;
+ } else {
+ p = ASN1_STRING_get0_data(oct);
+ plen = ASN1_STRING_length(oct);
+ }
+
+ /*
+ * EVP_PKEY_NONE means that ecx_key_op() has to figure out the key type
+ * on its own.
+ */
+ ecx = ossl_ecx_key_op(palg, p, plen, EVP_PKEY_NONE, KEY_OP_PRIVATE,
+ libctx, propq);
+ ASN1_OCTET_STRING_free(oct);
+ return ecx;
+}
+#endif
diff --git a/crypto/ec/ecx_backend.h b/crypto/ec/ecx_backend.h
new file mode 100644
index 000000000000..2c01294789b3
--- /dev/null
+++ b/crypto/ec/ecx_backend.h
@@ -0,0 +1,20 @@
+/*
+ * 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
+ */
+
+#define ISX448(id) ((id) == EVP_PKEY_X448)
+#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
+#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
+ : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
+ : ED448_KEYLEN))
+#define KEYNID2TYPE(id) \
+ (IS25519(id) ? ((id) == EVP_PKEY_X25519 ? ECX_KEY_TYPE_X25519 \
+ : ECX_KEY_TYPE_ED25519) \
+ : ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
+ : ECX_KEY_TYPE_ED448))
+#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c
new file mode 100644
index 000000000000..dcec26c2e9b3
--- /dev/null
+++ b/crypto/ec/ecx_key.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020-2021 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 "crypto/ecx.h"
+
+ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey,
+ const char *propq)
+{
+ ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL)
+ return NULL;
+
+ ret->libctx = libctx;
+ ret->haspubkey = haspubkey;
+ switch (type) {
+ case ECX_KEY_TYPE_X25519:
+ ret->keylen = X25519_KEYLEN;
+ break;
+ case ECX_KEY_TYPE_X448:
+ ret->keylen = X448_KEYLEN;
+ break;
+ case ECX_KEY_TYPE_ED25519:
+ ret->keylen = ED25519_KEYLEN;
+ break;
+ case ECX_KEY_TYPE_ED448:
+ ret->keylen = ED448_KEYLEN;
+ break;
+ }
+ ret->type = type;
+ ret->references = 1;
+
+ if (propq != NULL) {
+ ret->propq = OPENSSL_strdup(propq);
+ if (ret->propq == NULL)
+ goto err;
+ }
+
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL)
+ goto err;
+ return ret;
+err:
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+}
+
+void ossl_ecx_key_free(ECX_KEY *key)
+{
+ int i;
+
+ if (key == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&key->references, &i, key->lock);
+ REF_PRINT_COUNT("ECX_KEY", key);
+ if (i > 0)
+ return;
+ REF_ASSERT_ISNT(i < 0);
+
+ OPENSSL_free(key->propq);
+ OPENSSL_secure_clear_free(key->privkey, key->keylen);
+ CRYPTO_THREAD_lock_free(key->lock);
+ OPENSSL_free(key);
+}
+
+void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx)
+{
+ key->libctx = libctx;
+}
+
+int ossl_ecx_key_up_ref(ECX_KEY *key)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("ECX_KEY", key);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key)
+{
+ key->privkey = OPENSSL_secure_zalloc(key->keylen);
+
+ return key->privkey;
+}
diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c
index 9dc5259e4afc..c97dc472ac57 100644
--- a/crypto/ec/ecx_meth.c
+++ b/crypto/ec/ecx_meth.c
@@ -1,126 +1,32 @@
/*
- * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
*/
+/*
+ * ECDSA 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>
#include <openssl/ec.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include <openssl/rand.h>
+#include "internal/cryptlib.h"
+#include "internal/provider.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "crypto/ecx.h"
#include "ec_local.h"
#include "curve448/curve448_local.h"
-
-#define X25519_BITS 253
-#define X25519_SECURITY_BITS 128
-
-#define ED25519_SIGSIZE 64
-
-#define X448_BITS 448
-#define ED448_BITS 456
-#define X448_SECURITY_BITS 224
-
-#define ED448_SIGSIZE 114
-
-#define ISX448(id) ((id) == EVP_PKEY_X448)
-#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
-#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
- : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
- : ED448_KEYLEN))
-#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
-
-
-typedef enum {
- KEY_OP_PUBLIC,
- KEY_OP_PRIVATE,
- KEY_OP_KEYGEN
-} ecx_key_op_t;
-
-/* Setup EVP_PKEY using public, private or generation */
-static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
- const unsigned char *p, int plen, ecx_key_op_t op)
-{
- ECX_KEY *key = NULL;
- unsigned char *privkey, *pubkey;
-
- if (op != KEY_OP_KEYGEN) {
- if (palg != NULL) {
- int ptype;
-
- /* Algorithm parameters must be absent */
- X509_ALGOR_get0(NULL, &ptype, NULL, palg);
- if (ptype != V_ASN1_UNDEF) {
- ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
- return 0;
- }
- }
-
- if (p == NULL || plen != KEYLENID(id)) {
- ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
- return 0;
- }
- }
-
- key = OPENSSL_zalloc(sizeof(*key));
- if (key == NULL) {
- ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- pubkey = key->pubkey;
-
- if (op == KEY_OP_PUBLIC) {
- memcpy(pubkey, p, plen);
- } else {
- privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
- if (privkey == NULL) {
- ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (op == KEY_OP_KEYGEN) {
- if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
- OPENSSL_secure_free(privkey);
- key->privkey = NULL;
- goto err;
- }
- if (id == EVP_PKEY_X25519) {
- privkey[0] &= 248;
- privkey[X25519_KEYLEN - 1] &= 127;
- privkey[X25519_KEYLEN - 1] |= 64;
- } else if (id == EVP_PKEY_X448) {
- privkey[0] &= 252;
- privkey[X448_KEYLEN - 1] |= 128;
- }
- } else {
- memcpy(privkey, p, KEYLENID(id));
- }
- switch (id) {
- case EVP_PKEY_X25519:
- X25519_public_from_private(pubkey, privkey);
- break;
- case EVP_PKEY_ED25519:
- ED25519_public_from_private(pubkey, privkey);
- break;
- case EVP_PKEY_X448:
- X448_public_from_private(pubkey, privkey);
- break;
- case EVP_PKEY_ED448:
- ED448_public_from_private(pubkey, privkey);
- break;
- }
- }
-
- EVP_PKEY_assign(pkey, id, key);
- return 1;
- err:
- OPENSSL_free(key);
- return 0;
-}
+#include "ecx_backend.h"
static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
{
@@ -128,35 +34,42 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
unsigned char *penc;
if (ecxkey == NULL) {
- ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
return 0;
}
penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
if (penc == NULL) {
- ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
OPENSSL_free(penc);
- ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
-static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
{
const unsigned char *p;
int pklen;
X509_ALGOR *palg;
+ ECX_KEY *ecx;
+ int ret = 0;
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
- return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
- KEY_OP_PUBLIC);
+ ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id,
+ KEY_OP_PUBLIC, NULL, NULL);
+ if (ecx != NULL) {
+ ret = 1;
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
+ }
+ return ret;
}
static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
@@ -170,29 +83,18 @@ static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
}
-static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
+ OSSL_LIB_CTX *libctx, const char *propq)
{
- const unsigned char *p;
- int plen;
- ASN1_OCTET_STRING *oct = NULL;
- const X509_ALGOR *palg;
- int rv;
+ int ret = 0;
+ ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq);
- if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
- return 0;
-
- oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
- if (oct == NULL) {
- p = NULL;
- plen = 0;
- } else {
- p = ASN1_STRING_get0_data(oct);
- plen = ASN1_STRING_length(oct);
+ if (ecx != NULL) {
+ ret = 1;
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
}
- rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
- ASN1_STRING_clear_free(oct);
- return rv;
+ return ret;
}
static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
@@ -203,7 +105,7 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
int penclen;
if (ecxkey == NULL || ecxkey->privkey == NULL) {
- ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
return 0;
}
@@ -213,14 +115,14 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
if (penclen < 0) {
- ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
V_ASN1_UNDEF, NULL, penc, penclen)) {
OPENSSL_clear_free(penc, penclen);
- ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -254,9 +156,7 @@ static int ecx_security_bits(const EVP_PKEY *pkey)
static void ecx_free(EVP_PKEY *pkey)
{
- if (pkey->pkey.ecx != NULL)
- OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
- OPENSSL_free(pkey->pkey.ecx);
+ ossl_ecx_key_free(pkey->pkey.ecx);
}
/* "parameters" are always equal */
@@ -318,10 +218,16 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op) {
- case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
- return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
- KEY_OP_PUBLIC);
+ case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: {
+ ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id,
+ KEY_OP_PUBLIC, NULL, NULL);
+ if (ecx != NULL) {
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
+ return 1;
+ }
+ return 0;
+ }
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
if (pkey->pkey.ecx != NULL) {
unsigned char **ppt = arg2;
@@ -355,14 +261,38 @@ static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
size_t len)
{
- return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
- KEY_OP_PRIVATE);
+ OSSL_LIB_CTX *libctx = NULL;
+ ECX_KEY *ecx = NULL;
+
+ if (pkey->keymgmt != NULL)
+ libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt));
+
+ ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id,
+ KEY_OP_PRIVATE, libctx, NULL);
+
+ if (ecx != NULL) {
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
+ return 1;
+ }
+ return 0;
}
static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
{
- return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
- KEY_OP_PUBLIC);
+ OSSL_LIB_CTX *libctx = NULL;
+ ECX_KEY *ecx = NULL;
+
+ if (pkey->keymgmt != NULL)
+ libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt));
+
+ ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id,
+ KEY_OP_PUBLIC, libctx, NULL);
+
+ if (ecx != NULL) {
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
+ return 1;
+ }
+ return 0;
}
static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
@@ -406,7 +336,97 @@ static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
return 1;
}
-const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
+static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
+{
+ /*
+ * We provide no mechanism to "update" an ECX key once it has been set,
+ * therefore we do not have to maintain a dirty count.
+ */
+ return 1;
+}
+
+static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
+ OSSL_FUNC_keymgmt_import_fn *importer,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ const ECX_KEY *key = from->pkey.ecx;
+ OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
+ OSSL_PARAM *params = NULL;
+ int selection = 0;
+ int rv = 0;
+
+ if (tmpl == NULL)
+ return 0;
+
+ /* A key must at least have a public part */
+ if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
+ key->pubkey, key->keylen))
+ goto err;
+ selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
+
+ if (key->privkey != NULL) {
+ if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
+ OSSL_PKEY_PARAM_PRIV_KEY,
+ key->privkey, key->keylen))
+ goto err;
+ selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
+ }
+
+ params = OSSL_PARAM_BLD_to_param(tmpl);
+
+ /* We export, the provider imports */
+ rv = importer(to_keydata, selection, params);
+
+ err:
+ OSSL_PARAM_BLD_free(tmpl);
+ OSSL_PARAM_free(params);
+ return rv;
+}
+
+static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
+ int keytype)
+{
+ EVP_PKEY_CTX *pctx = vpctx;
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0,
+ pctx->propquery);
+
+ if (ecx == NULL) {
+ ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (!ossl_ecx_key_fromdata(ecx, params, 1)
+ || !EVP_PKEY_assign(pkey, keytype, ecx)) {
+ ossl_ecx_key_free(ecx);
+ return 0;
+ }
+ return 1;
+}
+
+static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
+{
+ ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL;
+ int ret;
+
+ if (ecx != NULL) {
+ dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL);
+ if (dupkey == NULL)
+ return 0;
+ }
+
+ ret = EVP_PKEY_assign(to, from->type, dupkey);
+ if (!ret)
+ ossl_ecx_key_free(dupkey);
+ return ret;
+}
+
+static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
+{
+ return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
+}
+
+const EVP_PKEY_ASN1_METHOD ossl_ecx25519_asn1_meth = {
EVP_PKEY_X25519,
EVP_PKEY_X25519,
0,
@@ -418,7 +438,7 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
ecx_pub_cmp,
ecx_pub_print,
- ecx_priv_decode,
+ NULL,
ecx_priv_encode,
ecx_priv_print,
@@ -447,9 +467,20 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
ecx_set_pub_key,
ecx_get_priv_key,
ecx_get_pub_key,
+ ecx_pkey_dirty_cnt,
+ ecx_pkey_export_to,
+ x25519_import_from,
+ ecx_pkey_copy,
+
+ ecx_priv_decode_ex
};
-const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
+static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
+{
+ return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
+}
+
+const EVP_PKEY_ASN1_METHOD ossl_ecx448_asn1_meth = {
EVP_PKEY_X448,
EVP_PKEY_X448,
0,
@@ -461,7 +492,7 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
ecx_pub_cmp,
ecx_pub_print,
- ecx_priv_decode,
+ NULL,
ecx_priv_encode,
ecx_priv_print,
@@ -490,6 +521,12 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
ecx_set_pub_key,
ecx_get_priv_key,
ecx_get_pub_key,
+ ecx_pkey_dirty_cnt,
+ ecx_pkey_export_to,
+ x448_import_from,
+ ecx_pkey_copy,
+
+ ecx_priv_decode_ex
};
static int ecd_size25519(const EVP_PKEY *pkey)
@@ -502,9 +539,9 @@ static int ecd_size448(const EVP_PKEY *pkey)
return ED448_SIGSIZE;
}
-static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
- X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
- EVP_PKEY *pkey)
+static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+ const void *asn, const X509_ALGOR *sigalg,
+ const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
{
const ASN1_OBJECT *obj;
int ptype;
@@ -514,7 +551,7 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
nid = OBJ_obj2nid(obj);
if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
- ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -524,7 +561,8 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
return 2;
}
-static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+ const void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
ASN1_BIT_STRING *str)
{
@@ -544,7 +582,8 @@ static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
return 1;
}
-static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
+ const void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
ASN1_BIT_STRING *str)
{
@@ -564,8 +603,12 @@ static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
return 1;
}
+static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
+{
+ return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
+}
-const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
+const EVP_PKEY_ASN1_METHOD ossl_ed25519_asn1_meth = {
EVP_PKEY_ED25519,
EVP_PKEY_ED25519,
0,
@@ -577,7 +620,7 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
ecx_pub_cmp,
ecx_pub_print,
- ecx_priv_decode,
+ NULL,
ecx_priv_encode,
ecx_priv_print,
@@ -605,9 +648,20 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
ecx_set_pub_key,
ecx_get_priv_key,
ecx_get_pub_key,
+ ecx_pkey_dirty_cnt,
+ ecx_pkey_export_to,
+ ed25519_import_from,
+ ecx_pkey_copy,
+
+ ecx_priv_decode_ex
};
-const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
+static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
+{
+ return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
+}
+
+const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = {
EVP_PKEY_ED448,
EVP_PKEY_ED448,
0,
@@ -619,7 +673,7 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
ecx_pub_cmp,
ecx_pub_print,
- ecx_priv_decode,
+ NULL,
ecx_priv_encode,
ecx_priv_print,
@@ -647,11 +701,24 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
ecx_set_pub_key,
ecx_get_priv_key,
ecx_get_pub_key,
+ ecx_pkey_dirty_cnt,
+ ecx_pkey_export_to,
+ ed448_import_from,
+ ecx_pkey_copy,
+
+ ecx_priv_decode_ex
};
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
- return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
+ ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id,
+ KEY_OP_KEYGEN, NULL, NULL);
+
+ if (ecx != NULL) {
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx);
+ return 1;
+ }
+ return 0;
}
static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
@@ -662,17 +729,17 @@ static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
const ECX_KEY *ecxkey, *peerkey;
if (ctx->pkey == NULL || ctx->peerkey == NULL) {
- ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
+ ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
return 0;
}
- ecxkey = ctx->pkey->pkey.ecx;
- peerkey = ctx->peerkey->pkey.ecx;
+ ecxkey = evp_pkey_get_legacy(ctx->pkey);
+ peerkey = evp_pkey_get_legacy(ctx->peerkey);
if (ecxkey == NULL || ecxkey->privkey == NULL) {
- ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
return 0;
}
if (peerkey == NULL) {
- ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY);
return 0;
}
*privkey = ecxkey->privkey;
@@ -688,7 +755,7 @@ static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
|| (key != NULL
- && X25519(key, privkey, pubkey) == 0))
+ && ossl_x25519(key, privkey, pubkey) == 0))
return 0;
*keylen = X25519_KEYLEN;
return 1;
@@ -701,7 +768,7 @@ static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
|| (key != NULL
- && X448(key, privkey, pubkey) == 0))
+ && ossl_x448(key, privkey, pubkey) == 0))
return 0;
*keylen = X448_KEYLEN;
return 1;
@@ -715,7 +782,7 @@ static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return -2;
}
-const EVP_PKEY_METHOD ecx25519_pkey_meth = {
+static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
EVP_PKEY_X25519,
0, 0, 0, 0, 0, 0, 0,
pkey_ecx_keygen,
@@ -725,7 +792,7 @@ const EVP_PKEY_METHOD ecx25519_pkey_meth = {
0
};
-const EVP_PKEY_METHOD ecx448_pkey_meth = {
+static const EVP_PKEY_METHOD ecx448_pkey_meth = {
EVP_PKEY_X448,
0, 0, 0, 0, 0, 0, 0,
pkey_ecx_keygen,
@@ -739,18 +806,24 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
size_t *siglen, const unsigned char *tbs,
size_t tbslen)
{
- const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
if (sig == NULL) {
*siglen = ED25519_SIGSIZE;
return 1;
}
if (*siglen < ED25519_SIGSIZE) {
- ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
- if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
+ if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
+ NULL) == 0)
return 0;
*siglen = ED25519_SIGSIZE;
return 1;
@@ -760,19 +833,24 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
size_t *siglen, const unsigned char *tbs,
size_t tbslen)
{
- const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
if (sig == NULL) {
*siglen = ED448_SIGSIZE;
return 1;
}
if (*siglen < ED448_SIGSIZE) {
- ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
- if (ED448_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
- 0) == 0)
+ if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey,
+ edkey->privkey, NULL, 0, edkey->propq) == 0)
return 0;
*siglen = ED448_SIGSIZE;
return 1;
@@ -782,24 +860,36 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs,
size_t tbslen)
{
- const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
if (siglen != ED25519_SIGSIZE)
return 0;
- return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
+ return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
+ edkey->libctx, edkey->propq);
}
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs,
size_t tbslen)
{
- const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
if (siglen != ED448_SIGSIZE)
return 0;
- return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0);
+ return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey,
+ NULL, 0, edkey->propq);
}
static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
@@ -809,7 +899,7 @@ static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
/* Only NULL allowed as digest */
if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
return 1;
- ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE);
return 0;
case EVP_PKEY_CTRL_DIGESTINIT:
@@ -818,7 +908,7 @@ static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return -2;
}
-const EVP_PKEY_METHOD ed25519_pkey_meth = {
+static const EVP_PKEY_METHOD ed25519_pkey_meth = {
EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
0, 0, 0, 0, 0, 0,
pkey_ecx_keygen,
@@ -829,7 +919,7 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = {
pkey_ecd_digestverify25519
};
-const EVP_PKEY_METHOD ed448_pkey_meth = {
+static const EVP_PKEY_METHOD ed448_pkey_meth = {
EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
0, 0, 0, 0, 0, 0,
pkey_ecx_keygen,
@@ -839,3 +929,496 @@ const EVP_PKEY_METHOD ed448_pkey_meth = {
pkey_ecd_digestsign448,
pkey_ecd_digestverify448
};
+
+#ifdef S390X_EC_ASM
+# include "s390x_arch.h"
+
+static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ static const unsigned char generator[] = {
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1,
+ ctx->propquery);
+ unsigned char *privkey = NULL, *pubkey;
+
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pubkey = key->pubkey;
+
+ privkey = ossl_ecx_key_allocate_privkey(key);
+ if (privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
+ goto err;
+
+ privkey[0] &= 248;
+ privkey[31] &= 127;
+ privkey[31] |= 64;
+
+ if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
+ goto err;
+
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
+ return 1;
+ err:
+ ossl_ecx_key_free(key);
+ return 0;
+}
+
+static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ static const unsigned char generator[] = {
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1,
+ ctx->propquery);
+ unsigned char *privkey = NULL, *pubkey;
+
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pubkey = key->pubkey;
+
+ privkey = ossl_ecx_key_allocate_privkey(key);
+ if (privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
+ goto err;
+
+ privkey[0] &= 252;
+ privkey[55] |= 128;
+
+ if (s390x_x448_mul(pubkey, generator, privkey) != 1)
+ goto err;
+
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
+ return 1;
+ err:
+ ossl_ecx_key_free(key);
+ return 0;
+}
+
+static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ static const unsigned char generator_x[] = {
+ 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
+ 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
+ 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
+ };
+ static const unsigned char generator_y[] = {
+ 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ };
+ unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
+ ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1,
+ ctx->propquery);
+ unsigned char *privkey = NULL, *pubkey;
+ unsigned int sz;
+ EVP_MD *md = NULL;
+ int rv;
+
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pubkey = key->pubkey;
+
+ privkey = ossl_ecx_key_allocate_privkey(key);
+ if (privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
+ goto err;
+
+ md = EVP_MD_fetch(ctx->libctx, "SHA512", ctx->propquery);
+ if (md == NULL)
+ goto err;
+
+ rv = EVP_Digest(privkey, 32, buff, &sz, md, NULL);
+ EVP_MD_free(md);
+ if (!rv)
+ goto err;
+
+ buff[0] &= 248;
+ buff[31] &= 63;
+ buff[31] |= 64;
+
+ if (s390x_ed25519_mul(x_dst, pubkey,
+ generator_x, generator_y, buff) != 1)
+ goto err;
+
+ pubkey[31] |= ((x_dst[0] & 0x01) << 7);
+
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
+ return 1;
+ err:
+ ossl_ecx_key_free(key);
+ return 0;
+}
+
+static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ static const unsigned char generator_x[] = {
+ 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
+ 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
+ 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
+ 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
+ 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
+ };
+ static const unsigned char generator_y[] = {
+ 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
+ 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
+ 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
+ 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
+ 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
+ };
+ unsigned char x_dst[57], buff[114];
+ ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1,
+ ctx->propquery);
+ unsigned char *privkey = NULL, *pubkey;
+ EVP_MD_CTX *hashctx = NULL;
+ EVP_MD *md = NULL;
+ int rv;
+
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ pubkey = key->pubkey;
+
+ privkey = ossl_ecx_key_allocate_privkey(key);
+ if (privkey == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
+ goto err;
+
+ hashctx = EVP_MD_CTX_new();
+ if (hashctx == NULL)
+ goto err;
+
+ md = EVP_MD_fetch(ctx->libctx, "SHAKE256", ctx->propquery);
+ if (md == NULL)
+ goto err;
+
+ rv = EVP_DigestInit_ex(hashctx, md, NULL);
+ EVP_MD_free(md);
+ if (rv != 1)
+ goto err;
+
+ if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
+ goto err;
+ if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
+ goto err;
+
+ buff[0] &= -4;
+ buff[55] |= 0x80;
+ buff[56] = 0;
+
+ if (s390x_ed448_mul(x_dst, pubkey,
+ generator_x, generator_y, buff) != 1)
+ goto err;
+
+ pubkey[56] |= ((x_dst[0] & 0x01) << 7);
+
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
+ EVP_MD_CTX_free(hashctx);
+ return 1;
+ err:
+ ossl_ecx_key_free(key);
+ EVP_MD_CTX_free(hashctx);
+ return 0;
+}
+
+static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
+ size_t *keylen)
+{
+ const unsigned char *privkey, *pubkey;
+
+ if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
+ || (key != NULL
+ && s390x_x25519_mul(key, privkey, pubkey) == 0))
+ return 0;
+ *keylen = X25519_KEYLEN;
+ return 1;
+}
+
+static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
+ size_t *keylen)
+{
+ const unsigned char *privkey, *pubkey;
+
+ if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
+ || (key != NULL
+ && s390x_x448_mul(key, pubkey, privkey) == 0))
+ return 0;
+ *keylen = X448_KEYLEN;
+ return 1;
+}
+
+static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[64];
+ unsigned char priv[32];
+ } ed25519;
+ unsigned long long buff[512];
+ } param;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+ int rc;
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
+
+ if (sig == NULL) {
+ *siglen = ED25519_SIGSIZE;
+ return 1;
+ }
+
+ if (*siglen < ED25519_SIGSIZE) {
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ memset(&param, 0, sizeof(param));
+ memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
+
+ rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
+ OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
+ if (rc != 0)
+ return 0;
+
+ s390x_flip_endian32(sig, param.ed25519.sig);
+ s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
+
+ *siglen = ED25519_SIGSIZE;
+ return 1;
+}
+
+static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[128];
+ unsigned char priv[64];
+ } ed448;
+ unsigned long long buff[512];
+ } param;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+ int rc;
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
+
+ if (sig == NULL) {
+ *siglen = ED448_SIGSIZE;
+ return 1;
+ }
+
+ if (*siglen < ED448_SIGSIZE) {
+ ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ memset(&param, 0, sizeof(param));
+ memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
+
+ rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
+ OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
+ if (rc != 0)
+ return 0;
+
+ s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
+ s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
+ memcpy(sig, param.ed448.sig, 57);
+ memcpy(sig + 57, param.ed448.sig + 64, 57);
+
+ *siglen = ED448_SIGSIZE;
+ return 1;
+}
+
+static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[64];
+ unsigned char pub[32];
+ } ed25519;
+ unsigned long long buff[512];
+ } param;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
+
+ if (siglen != ED25519_SIGSIZE)
+ return 0;
+
+ memset(&param, 0, sizeof(param));
+ s390x_flip_endian32(param.ed25519.sig, sig);
+ s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
+ s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
+
+ return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
+ &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
+}
+
+static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[128];
+ unsigned char pub[64];
+ } ed448;
+ unsigned long long buff[512];
+ } param;
+ const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
+
+ if (edkey == NULL) {
+ ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
+ return 0;
+ }
+
+ if (siglen != ED448_SIGSIZE)
+ return 0;
+
+ memset(&param, 0, sizeof(param));
+ memcpy(param.ed448.sig, sig, 57);
+ s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
+ memcpy(param.ed448.sig + 64, sig + 57, 57);
+ s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
+ memcpy(param.ed448.pub, edkey->pubkey, 57);
+ s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
+
+ return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
+ &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
+}
+
+static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
+ EVP_PKEY_X25519,
+ 0, 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecx_keygen25519,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecx_derive25519,
+ pkey_ecx_ctrl,
+ 0
+};
+
+static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
+ EVP_PKEY_X448,
+ 0, 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecx_keygen448,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecx_derive448,
+ pkey_ecx_ctrl,
+ 0
+};
+static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
+ EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+ 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecd_keygen25519,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pkey_ecd_ctrl,
+ 0,
+ s390x_pkey_ecd_digestsign25519,
+ s390x_pkey_ecd_digestverify25519
+};
+
+static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
+ EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+ 0, 0, 0, 0, 0, 0,
+ s390x_pkey_ecd_keygen448,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pkey_ecd_ctrl,
+ 0,
+ s390x_pkey_ecd_digestsign448,
+ s390x_pkey_ecd_digestverify448
+};
+#endif
+
+const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void)
+{
+#ifdef S390X_EC_ASM
+ if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
+ return &ecx25519_s390x_pkey_meth;
+#endif
+ return &ecx25519_pkey_meth;
+}
+
+const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void)
+{
+#ifdef S390X_EC_ASM
+ if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
+ return &ecx448_s390x_pkey_meth;
+#endif
+ return &ecx448_pkey_meth;
+}
+
+const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void)
+{
+#ifdef S390X_EC_ASM
+ if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
+ && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
+ && OPENSSL_s390xcap_P.kdsa[0]
+ & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
+ return &ed25519_s390x_pkey_meth;
+#endif
+ return &ed25519_pkey_meth;
+}
+
+const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void)
+{
+#ifdef S390X_EC_ASM
+ if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
+ && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
+ && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
+ return &ed448_s390x_pkey_meth;
+#endif
+ return &ed448_pkey_meth;
+}
diff --git a/crypto/ec/ecx_s390x.c b/crypto/ec/ecx_s390x.c
new file mode 100644
index 000000000000..d424d6252dcf
--- /dev/null
+++ b/crypto/ec/ecx_s390x.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2006-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/ec.h>
+#include <openssl/rand.h>
+#include "crypto/ecx.h"
+#include "ec_local.h"
+#include "curve448/curve448_local.h"
+#include "ecx_backend.h"
+#include "s390x_arch.h"
+#include "internal/constant_time.h"
+
+static void s390x_x25519_mod_p(unsigned char u[32])
+{
+ unsigned char u_red[32];
+ unsigned int c = 0;
+ int i;
+
+ memcpy(u_red, u, sizeof(u_red));
+
+ c += (unsigned int)u_red[31] + 19;
+ u_red[31] = (unsigned char)c;
+ c >>= 8;
+
+ for (i = 30; i >= 0; i--) {
+ c += (unsigned int)u_red[i];
+ u_red[i] = (unsigned char)c;
+ c >>= 8;
+ }
+
+ c = (u_red[0] & 0x80) >> 7;
+ u_red[0] &= 0x7f;
+ constant_time_cond_swap_buff(0 - (unsigned char)c,
+ u, u_red, sizeof(u_red));
+}
+
+static void s390x_x448_mod_p(unsigned char u[56])
+{
+ unsigned char u_red[56];
+ unsigned int c = 0;
+ int i;
+
+ memcpy(u_red, u, sizeof(u_red));
+
+ c += (unsigned int)u_red[55] + 1;
+ u_red[55] = (unsigned char)c;
+ c >>= 8;
+
+ for (i = 54; i >= 28; i--) {
+ c += (unsigned int)u_red[i];
+ u_red[i] = (unsigned char)c;
+ c >>= 8;
+ }
+
+ c += (unsigned int)u_red[27] + 1;
+ u_red[27] = (unsigned char)c;
+ c >>= 8;
+
+ for (i = 26; i >= 0; i--) {
+ c += (unsigned int)u_red[i];
+ u_red[i] = (unsigned char)c;
+ c >>= 8;
+ }
+
+ constant_time_cond_swap_buff(0 - (unsigned char)c,
+ u, u_red, sizeof(u_red));
+}
+
+int s390x_x25519_mul(unsigned char u_dst[32],
+ const unsigned char u_src[32],
+ const unsigned char d_src[32])
+{
+ union {
+ struct {
+ unsigned char u_dst[32];
+ unsigned char u_src[32];
+ unsigned char d_src[32];
+ } x25519;
+ unsigned long long buff[512];
+ } param;
+ int rc;
+
+ memset(&param, 0, sizeof(param));
+
+ s390x_flip_endian32(param.x25519.u_src, u_src);
+ param.x25519.u_src[0] &= 0x7f;
+ s390x_x25519_mod_p(param.x25519.u_src);
+
+ s390x_flip_endian32(param.x25519.d_src, d_src);
+ param.x25519.d_src[31] &= 248;
+ param.x25519.d_src[0] &= 127;
+ param.x25519.d_src[0] |= 64;
+
+ rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, &param.x25519) ? 0 : 1;
+ if (rc == 1)
+ s390x_flip_endian32(u_dst, param.x25519.u_dst);
+
+ OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
+ return rc;
+}
+
+int s390x_x448_mul(unsigned char u_dst[56],
+ const unsigned char u_src[56],
+ const unsigned char d_src[56])
+{
+ union {
+ struct {
+ unsigned char u_dst[64];
+ unsigned char u_src[64];
+ unsigned char d_src[64];
+ } x448;
+ unsigned long long buff[512];
+ } param;
+ int rc;
+
+ memset(&param, 0, sizeof(param));
+
+ memcpy(param.x448.u_src, u_src, 56);
+ memcpy(param.x448.d_src, d_src, 56);
+
+ s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
+ s390x_x448_mod_p(param.x448.u_src + 8);
+
+ s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
+ param.x448.d_src[63] &= 252;
+ param.x448.d_src[8] |= 128;
+
+ rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, &param.x448) ? 0 : 1;
+ if (rc == 1) {
+ s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
+ memcpy(u_dst, param.x448.u_dst, 56);
+ }
+
+ OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
+ return rc;
+}
+
+int s390x_ed25519_mul(unsigned char x_dst[32],
+ unsigned char y_dst[32],
+ const unsigned char x_src[32],
+ const unsigned char y_src[32],
+ const unsigned char d_src[32])
+{
+ union {
+ struct {
+ unsigned char x_dst[32];
+ unsigned char y_dst[32];
+ unsigned char x_src[32];
+ unsigned char y_src[32];
+ unsigned char d_src[32];
+ } ed25519;
+ unsigned long long buff[512];
+ } param;
+ int rc;
+
+ memset(&param, 0, sizeof(param));
+
+ s390x_flip_endian32(param.ed25519.x_src, x_src);
+ s390x_flip_endian32(param.ed25519.y_src, y_src);
+ s390x_flip_endian32(param.ed25519.d_src, d_src);
+
+ rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, &param.ed25519) ? 0 : 1;
+ if (rc == 1) {
+ s390x_flip_endian32(x_dst, param.ed25519.x_dst);
+ s390x_flip_endian32(y_dst, param.ed25519.y_dst);
+ }
+
+ OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
+ return rc;
+}
+
+int s390x_ed448_mul(unsigned char x_dst[57],
+ unsigned char y_dst[57],
+ const unsigned char x_src[57],
+ const unsigned char y_src[57],
+ const unsigned char d_src[57])
+{
+ union {
+ struct {
+ unsigned char x_dst[64];
+ unsigned char y_dst[64];
+ unsigned char x_src[64];
+ unsigned char y_src[64];
+ unsigned char d_src[64];
+ } ed448;
+ unsigned long long buff[512];
+ } param;
+ int rc;
+
+ memset(&param, 0, sizeof(param));
+
+ memcpy(param.ed448.x_src, x_src, 57);
+ memcpy(param.ed448.y_src, y_src, 57);
+ memcpy(param.ed448.d_src, d_src, 57);
+ s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
+ s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
+ s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
+
+ rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, &param.ed448) ? 0 : 1;
+ if (rc == 1) {
+ s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
+ s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
+ memcpy(x_dst, param.ed448.x_dst, 57);
+ memcpy(y_dst, param.ed448.y_dst, 57);
+ }
+
+ OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
+ return rc;
+}