mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
AppleM1: Update openssl to v1.1.1l
This commit is contained in:
parent
1fe12b8e8c
commit
b787656eea
990 changed files with 13406 additions and 18710 deletions
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2018 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
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -1394,7 +1394,7 @@ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
|
|||
# 256-bit vectors on top. Then note that we push
|
||||
# starting from r0, which means that we have copy of
|
||||
# input arguments just below these temporary vectors.
|
||||
# We use three of them for !in1infty, !in2intfy and
|
||||
# We use three of them for ~in1infty, ~in2infty and
|
||||
# result of check for zero.
|
||||
|
||||
$code.=<<___;
|
||||
|
@ -1424,7 +1424,7 @@ ecp_nistz256_point_add:
|
|||
#endif
|
||||
movne r12,#-1
|
||||
stmia r3,{r4-r11}
|
||||
str r12,[sp,#32*18+8] @ !in2infty
|
||||
str r12,[sp,#32*18+8] @ ~in2infty
|
||||
|
||||
ldmia $a_ptr!,{r4-r11} @ copy in1_x
|
||||
add r3,sp,#$in1_x
|
||||
|
@ -1445,7 +1445,7 @@ ecp_nistz256_point_add:
|
|||
#endif
|
||||
movne r12,#-1
|
||||
stmia r3,{r4-r11}
|
||||
str r12,[sp,#32*18+4] @ !in1infty
|
||||
str r12,[sp,#32*18+4] @ ~in1infty
|
||||
|
||||
add $a_ptr,sp,#$in2_z
|
||||
add $b_ptr,sp,#$in2_z
|
||||
|
@ -1510,33 +1510,20 @@ ecp_nistz256_point_add:
|
|||
orr $a0,$a0,$a2
|
||||
orr $a4,$a4,$a6
|
||||
orr $a0,$a0,$a7
|
||||
orrs $a0,$a0,$a4
|
||||
orr $a0,$a0,$a4 @ ~is_equal(U1,U2)
|
||||
|
||||
bne .Ladd_proceed @ is_equal(U1,U2)?
|
||||
ldr $t0,[sp,#32*18+4] @ ~in1infty
|
||||
ldr $t1,[sp,#32*18+8] @ ~in2infty
|
||||
ldr $t2,[sp,#32*18+12] @ ~is_equal(S1,S2)
|
||||
mvn $t0,$t0 @ -1/0 -> 0/-1
|
||||
mvn $t1,$t1 @ -1/0 -> 0/-1
|
||||
orr $a0,$a0,$t0
|
||||
orr $a0,$a0,$t1
|
||||
orrs $a0,$a0,$t2 @ set flags
|
||||
|
||||
ldr $t0,[sp,#32*18+4]
|
||||
ldr $t1,[sp,#32*18+8]
|
||||
ldr $t2,[sp,#32*18+12]
|
||||
tst $t0,$t1
|
||||
beq .Ladd_proceed @ (in1infty || in2infty)?
|
||||
tst $t2,$t2
|
||||
beq .Ladd_double @ is_equal(S1,S2)?
|
||||
@ if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2))
|
||||
bne .Ladd_proceed
|
||||
|
||||
ldr $r_ptr,[sp,#32*18+16]
|
||||
eor r4,r4,r4
|
||||
eor r5,r5,r5
|
||||
eor r6,r6,r6
|
||||
eor r7,r7,r7
|
||||
eor r8,r8,r8
|
||||
eor r9,r9,r9
|
||||
eor r10,r10,r10
|
||||
eor r11,r11,r11
|
||||
stmia $r_ptr!,{r4-r11}
|
||||
stmia $r_ptr!,{r4-r11}
|
||||
stmia $r_ptr!,{r4-r11}
|
||||
b .Ladd_done
|
||||
|
||||
.align 4
|
||||
.Ladd_double:
|
||||
ldr $a_ptr,[sp,#32*18+20]
|
||||
add sp,sp,#32*(18-5)+16 @ difference in frame sizes
|
||||
|
@ -1601,15 +1588,15 @@ ecp_nistz256_point_add:
|
|||
add $b_ptr,sp,#$S2
|
||||
bl __ecp_nistz256_sub_from @ p256_sub(res_y, res_y, S2);
|
||||
|
||||
ldr r11,[sp,#32*18+4] @ !in1intfy
|
||||
ldr r12,[sp,#32*18+8] @ !in2intfy
|
||||
ldr r11,[sp,#32*18+4] @ ~in1infty
|
||||
ldr r12,[sp,#32*18+8] @ ~in2infty
|
||||
add r1,sp,#$res_x
|
||||
add r2,sp,#$in2_x
|
||||
and r10,r11,r12
|
||||
and r10,r11,r12 @ ~in1infty & ~in2infty
|
||||
mvn r11,r11
|
||||
add r3,sp,#$in1_x
|
||||
and r11,r11,r12
|
||||
mvn r12,r12
|
||||
and r11,r11,r12 @ in1infty & ~in2infty
|
||||
mvn r12,r12 @ in2infty
|
||||
ldr $r_ptr,[sp,#32*18+16]
|
||||
___
|
||||
for($i=0;$i<96;$i+=8) { # conditional moves
|
||||
|
@ -1617,11 +1604,11 @@ $code.=<<___;
|
|||
ldmia r1!,{r4-r5} @ res_x
|
||||
ldmia r2!,{r6-r7} @ in2_x
|
||||
ldmia r3!,{r8-r9} @ in1_x
|
||||
and r4,r4,r10
|
||||
and r4,r4,r10 @ ~in1infty & ~in2infty
|
||||
and r5,r5,r10
|
||||
and r6,r6,r11
|
||||
and r6,r6,r11 @ in1infty & ~in2infty
|
||||
and r7,r7,r11
|
||||
and r8,r8,r12
|
||||
and r8,r8,r12 @ in2infty
|
||||
and r9,r9,r12
|
||||
orr r4,r4,r6
|
||||
orr r5,r5,r7
|
||||
|
@ -1656,7 +1643,7 @@ my $Z1sqr = $S2;
|
|||
# 256-bit vectors on top. Then note that we push
|
||||
# starting from r0, which means that we have copy of
|
||||
# input arguments just below these temporary vectors.
|
||||
# We use two of them for !in1infty, !in2intfy.
|
||||
# We use two of them for ~in1infty, ~in2infty.
|
||||
|
||||
my @ONE_mont=(1,0,0,-1,-1,-1,-2,0);
|
||||
|
||||
|
@ -1687,7 +1674,7 @@ ecp_nistz256_point_add_affine:
|
|||
#endif
|
||||
movne r12,#-1
|
||||
stmia r3,{r4-r11}
|
||||
str r12,[sp,#32*15+4] @ !in1infty
|
||||
str r12,[sp,#32*15+4] @ ~in1infty
|
||||
|
||||
ldmia $b_ptr!,{r4-r11} @ copy in2_x
|
||||
add r3,sp,#$in2_x
|
||||
|
@ -1714,7 +1701,7 @@ ecp_nistz256_point_add_affine:
|
|||
it ne
|
||||
#endif
|
||||
movne r12,#-1
|
||||
str r12,[sp,#32*15+8] @ !in2infty
|
||||
str r12,[sp,#32*15+8] @ ~in2infty
|
||||
|
||||
add $a_ptr,sp,#$in1_z
|
||||
add $b_ptr,sp,#$in1_z
|
||||
|
@ -1796,15 +1783,15 @@ ecp_nistz256_point_add_affine:
|
|||
add $b_ptr,sp,#$S2
|
||||
bl __ecp_nistz256_sub_from @ p256_sub(res_y, res_y, S2);
|
||||
|
||||
ldr r11,[sp,#32*15+4] @ !in1intfy
|
||||
ldr r12,[sp,#32*15+8] @ !in2intfy
|
||||
ldr r11,[sp,#32*15+4] @ ~in1infty
|
||||
ldr r12,[sp,#32*15+8] @ ~in2infty
|
||||
add r1,sp,#$res_x
|
||||
add r2,sp,#$in2_x
|
||||
and r10,r11,r12
|
||||
and r10,r11,r12 @ ~in1infty & ~in2infty
|
||||
mvn r11,r11
|
||||
add r3,sp,#$in1_x
|
||||
and r11,r11,r12
|
||||
mvn r12,r12
|
||||
and r11,r11,r12 @ in1infty & ~in2infty
|
||||
mvn r12,r12 @ in2infty
|
||||
ldr $r_ptr,[sp,#32*15]
|
||||
___
|
||||
for($i=0;$i<64;$i+=8) { # conditional moves
|
||||
|
@ -1812,11 +1799,11 @@ $code.=<<___;
|
|||
ldmia r1!,{r4-r5} @ res_x
|
||||
ldmia r2!,{r6-r7} @ in2_x
|
||||
ldmia r3!,{r8-r9} @ in1_x
|
||||
and r4,r4,r10
|
||||
and r4,r4,r10 @ ~in1infty & ~in2infty
|
||||
and r5,r5,r10
|
||||
and r6,r6,r11
|
||||
and r6,r6,r11 @ in1infty & ~in2infty
|
||||
and r7,r7,r11
|
||||
and r8,r8,r12
|
||||
and r8,r8,r12 @ in2infty
|
||||
and r9,r9,r12
|
||||
orr r4,r4,r6
|
||||
orr r5,r5,r7
|
||||
|
@ -1862,4 +1849,4 @@ foreach (split("\n",$code)) {
|
|||
|
||||
print $_,"\n";
|
||||
}
|
||||
close STDOUT; # enforce flush
|
||||
close STDOUT or die "error closing STDOUT: $!"; # enforce flush
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2019 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
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -722,7 +722,7 @@ $code.=<<___;
|
|||
.align 5
|
||||
ecp_nistz256_point_double:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29,x30,[sp,#-80]!
|
||||
stp x29,x30,[sp,#-96]!
|
||||
add x29,sp,#0
|
||||
stp x19,x20,[sp,#16]
|
||||
stp x21,x22,[sp,#32]
|
||||
|
@ -855,7 +855,7 @@ ecp_nistz256_point_double:
|
|||
add sp,x29,#0 // destroy frame
|
||||
ldp x19,x20,[x29,#16]
|
||||
ldp x21,x22,[x29,#32]
|
||||
ldp x29,x30,[sp],#80
|
||||
ldp x29,x30,[sp],#96
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
|
||||
|
@ -872,7 +872,7 @@ my ($res_x,$res_y,$res_z,
|
|||
my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
|
||||
# above map() describes stack layout with 12 temporary
|
||||
# 256-bit vectors on top.
|
||||
my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26));
|
||||
my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp0,$temp1,$temp2)=map("x$_",(21..28));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_point_add
|
||||
|
@ -880,12 +880,13 @@ $code.=<<___;
|
|||
.align 5
|
||||
ecp_nistz256_point_add:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29,x30,[sp,#-80]!
|
||||
stp x29,x30,[sp,#-96]!
|
||||
add x29,sp,#0
|
||||
stp x19,x20,[sp,#16]
|
||||
stp x21,x22,[sp,#32]
|
||||
stp x23,x24,[sp,#48]
|
||||
stp x25,x26,[sp,#64]
|
||||
stp x27,x28,[sp,#80]
|
||||
sub sp,sp,#32*12
|
||||
|
||||
ldp $a0,$a1,[$bp,#64] // in2_z
|
||||
|
@ -899,7 +900,7 @@ ecp_nistz256_point_add:
|
|||
orr $t2,$a2,$a3
|
||||
orr $in2infty,$t0,$t2
|
||||
cmp $in2infty,#0
|
||||
csetm $in2infty,ne // !in2infty
|
||||
csetm $in2infty,ne // ~in2infty
|
||||
add $rp,sp,#$Z2sqr
|
||||
bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z);
|
||||
|
||||
|
@ -909,7 +910,7 @@ ecp_nistz256_point_add:
|
|||
orr $t2,$a2,$a3
|
||||
orr $in1infty,$t0,$t2
|
||||
cmp $in1infty,#0
|
||||
csetm $in1infty,ne // !in1infty
|
||||
csetm $in1infty,ne // ~in1infty
|
||||
add $rp,sp,#$Z1sqr
|
||||
bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
|
||||
|
||||
|
@ -950,7 +951,7 @@ ecp_nistz256_point_add:
|
|||
|
||||
orr $acc0,$acc0,$acc1 // see if result is zero
|
||||
orr $acc2,$acc2,$acc3
|
||||
orr $temp,$acc0,$acc2
|
||||
orr $temp0,$acc0,$acc2 // ~is_equal(S1,S2)
|
||||
|
||||
add $bp,sp,#$Z2sqr
|
||||
add $rp,sp,#$U1
|
||||
|
@ -971,32 +972,21 @@ ecp_nistz256_point_add:
|
|||
|
||||
orr $acc0,$acc0,$acc1 // see if result is zero
|
||||
orr $acc2,$acc2,$acc3
|
||||
orr $acc0,$acc0,$acc2
|
||||
tst $acc0,$acc0
|
||||
b.ne .Ladd_proceed // is_equal(U1,U2)?
|
||||
orr $acc0,$acc0,$acc2 // ~is_equal(U1,U2)
|
||||
|
||||
tst $in1infty,$in2infty
|
||||
b.eq .Ladd_proceed // (in1infty || in2infty)?
|
||||
mvn $temp1,$in1infty // -1/0 -> 0/-1
|
||||
mvn $temp2,$in2infty // -1/0 -> 0/-1
|
||||
orr $acc0,$acc0,$temp1
|
||||
orr $acc0,$acc0,$temp2
|
||||
orr $acc0,$acc0,$temp0
|
||||
cbnz $acc0,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2))
|
||||
|
||||
tst $temp,$temp
|
||||
b.eq .Ladd_double // is_equal(S1,S2)?
|
||||
|
||||
eor $a0,$a0,$a0
|
||||
eor $a1,$a1,$a1
|
||||
stp $a0,$a1,[$rp_real]
|
||||
stp $a0,$a1,[$rp_real,#16]
|
||||
stp $a0,$a1,[$rp_real,#32]
|
||||
stp $a0,$a1,[$rp_real,#48]
|
||||
stp $a0,$a1,[$rp_real,#64]
|
||||
stp $a0,$a1,[$rp_real,#80]
|
||||
b .Ladd_done
|
||||
|
||||
.align 4
|
||||
.Ladd_double:
|
||||
mov $ap,$ap_real
|
||||
mov $rp,$rp_real
|
||||
ldp x23,x24,[x29,#48]
|
||||
ldp x25,x26,[x29,#64]
|
||||
ldp x27,x28,[x29,#80]
|
||||
add sp,sp,#32*(12-4) // difference in stack frames
|
||||
b .Ldouble_shortcut
|
||||
|
||||
|
@ -1081,14 +1071,14 @@ ___
|
|||
for($i=0;$i<64;$i+=32) { # conditional moves
|
||||
$code.=<<___;
|
||||
ldp $acc0,$acc1,[$ap_real,#$i] // in1
|
||||
cmp $in1infty,#0 // !$in1intfy, remember?
|
||||
cmp $in1infty,#0 // ~$in1intfy, remember?
|
||||
ldp $acc2,$acc3,[$ap_real,#$i+16]
|
||||
csel $t0,$a0,$t0,ne
|
||||
csel $t1,$a1,$t1,ne
|
||||
ldp $a0,$a1,[sp,#$res_x+$i+32] // res
|
||||
csel $t2,$a2,$t2,ne
|
||||
csel $t3,$a3,$t3,ne
|
||||
cmp $in2infty,#0 // !$in2intfy, remember?
|
||||
cmp $in2infty,#0 // ~$in2intfy, remember?
|
||||
ldp $a2,$a3,[sp,#$res_x+$i+48]
|
||||
csel $acc0,$t0,$acc0,ne
|
||||
csel $acc1,$t1,$acc1,ne
|
||||
|
@ -1102,13 +1092,13 @@ ___
|
|||
}
|
||||
$code.=<<___;
|
||||
ldp $acc0,$acc1,[$ap_real,#$i] // in1
|
||||
cmp $in1infty,#0 // !$in1intfy, remember?
|
||||
cmp $in1infty,#0 // ~$in1intfy, remember?
|
||||
ldp $acc2,$acc3,[$ap_real,#$i+16]
|
||||
csel $t0,$a0,$t0,ne
|
||||
csel $t1,$a1,$t1,ne
|
||||
csel $t2,$a2,$t2,ne
|
||||
csel $t3,$a3,$t3,ne
|
||||
cmp $in2infty,#0 // !$in2intfy, remember?
|
||||
cmp $in2infty,#0 // ~$in2intfy, remember?
|
||||
csel $acc0,$t0,$acc0,ne
|
||||
csel $acc1,$t1,$acc1,ne
|
||||
csel $acc2,$t2,$acc2,ne
|
||||
|
@ -1122,7 +1112,8 @@ $code.=<<___;
|
|||
ldp x21,x22,[x29,#32]
|
||||
ldp x23,x24,[x29,#48]
|
||||
ldp x25,x26,[x29,#64]
|
||||
ldp x29,x30,[sp],#80
|
||||
ldp x27,x28,[x29,#80]
|
||||
ldp x29,x30,[sp],#96
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
|
||||
|
@ -1166,7 +1157,7 @@ ecp_nistz256_point_add_affine:
|
|||
orr $t2,$a2,$a3
|
||||
orr $in1infty,$t0,$t2
|
||||
cmp $in1infty,#0
|
||||
csetm $in1infty,ne // !in1infty
|
||||
csetm $in1infty,ne // ~in1infty
|
||||
|
||||
ldp $acc0,$acc1,[$bp] // in2_x
|
||||
ldp $acc2,$acc3,[$bp,#16]
|
||||
|
@ -1180,7 +1171,7 @@ ecp_nistz256_point_add_affine:
|
|||
orr $t0,$t0,$t2
|
||||
orr $in2infty,$acc0,$t0
|
||||
cmp $in2infty,#0
|
||||
csetm $in2infty,ne // !in2infty
|
||||
csetm $in2infty,ne // ~in2infty
|
||||
|
||||
add $rp,sp,#$Z1sqr
|
||||
bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
|
||||
|
@ -1290,14 +1281,14 @@ ___
|
|||
for($i=0;$i<64;$i+=32) { # conditional moves
|
||||
$code.=<<___;
|
||||
ldp $acc0,$acc1,[$ap_real,#$i] // in1
|
||||
cmp $in1infty,#0 // !$in1intfy, remember?
|
||||
cmp $in1infty,#0 // ~$in1intfy, remember?
|
||||
ldp $acc2,$acc3,[$ap_real,#$i+16]
|
||||
csel $t0,$a0,$t0,ne
|
||||
csel $t1,$a1,$t1,ne
|
||||
ldp $a0,$a1,[sp,#$res_x+$i+32] // res
|
||||
csel $t2,$a2,$t2,ne
|
||||
csel $t3,$a3,$t3,ne
|
||||
cmp $in2infty,#0 // !$in2intfy, remember?
|
||||
cmp $in2infty,#0 // ~$in2intfy, remember?
|
||||
ldp $a2,$a3,[sp,#$res_x+$i+48]
|
||||
csel $acc0,$t0,$acc0,ne
|
||||
csel $acc1,$t1,$acc1,ne
|
||||
|
@ -1314,13 +1305,13 @@ ___
|
|||
}
|
||||
$code.=<<___;
|
||||
ldp $acc0,$acc1,[$ap_real,#$i] // in1
|
||||
cmp $in1infty,#0 // !$in1intfy, remember?
|
||||
cmp $in1infty,#0 // ~$in1intfy, remember?
|
||||
ldp $acc2,$acc3,[$ap_real,#$i+16]
|
||||
csel $t0,$a0,$t0,ne
|
||||
csel $t1,$a1,$t1,ne
|
||||
csel $t2,$a2,$t2,ne
|
||||
csel $t3,$a3,$t3,ne
|
||||
cmp $in2infty,#0 // !$in2intfy, remember?
|
||||
cmp $in2infty,#0 // ~$in2intfy, remember?
|
||||
csel $acc0,$t0,$acc0,ne
|
||||
csel $acc1,$t1,$acc1,ne
|
||||
csel $acc2,$t2,$acc2,ne
|
||||
|
@ -1880,4 +1871,4 @@ foreach (split("\n",$code)) {
|
|||
|
||||
print $_,"\n";
|
||||
}
|
||||
close STDOUT; # enforce flush
|
||||
close STDOUT or die "error closing STDOUT: $!"; # enforce flush
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -2379,4 +2379,4 @@ foreach (split("\n",$code)) {
|
|||
|
||||
print $_,"\n";
|
||||
}
|
||||
close STDOUT; # enforce flush
|
||||
close STDOUT or die "error closing STDOUT: $!"; # enforce flush
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2018 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
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -2301,7 +2301,6 @@ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
|
|||
# !in1infty, !in2infty and result of check for zero.
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_point_add_vis3
|
||||
.align 32
|
||||
ecp_nistz256_point_add_vis3:
|
||||
save %sp,-STACK64_FRAME-32*18-32,%sp
|
||||
|
@ -3058,4 +3057,4 @@ foreach (split("\n",$code)) {
|
|||
print $_,"\n";
|
||||
}
|
||||
|
||||
close STDOUT;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2018 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
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -1388,7 +1388,7 @@ for ($i=0;$i<7;$i++) {
|
|||
|
||||
# above map() describes stack layout with 18 temporary
|
||||
# 256-bit vectors on top, then we take extra words for
|
||||
# !in1infty, !in2infty, result of check for zero and
|
||||
# ~in1infty, ~in2infty, result of check for zero and
|
||||
# OPENSSL_ia32cap_P copy. [one unused word for padding]
|
||||
&stack_push(8*18+5);
|
||||
if ($sse2) {
|
||||
|
@ -1419,7 +1419,7 @@ for ($i=0;$i<7;$i++) {
|
|||
&sub ("eax","ebp");
|
||||
&or ("ebp","eax");
|
||||
&sar ("ebp",31);
|
||||
&mov (&DWP(32*18+4,"esp"),"ebp"); # !in2infty
|
||||
&mov (&DWP(32*18+4,"esp"),"ebp"); # ~in2infty
|
||||
|
||||
&lea ("edi",&DWP($in1_x,"esp"));
|
||||
for($i=0;$i<96;$i+=16) {
|
||||
|
@ -1441,7 +1441,7 @@ for ($i=0;$i<7;$i++) {
|
|||
&sub ("eax","ebp");
|
||||
&or ("ebp","eax");
|
||||
&sar ("ebp",31);
|
||||
&mov (&DWP(32*18+0,"esp"),"ebp"); # !in1infty
|
||||
&mov (&DWP(32*18+0,"esp"),"ebp"); # ~in1infty
|
||||
|
||||
&mov ("eax",&DWP(32*18+12,"esp")); # OPENSSL_ia32cap_P copy
|
||||
&lea ("esi",&DWP($in2_z,"esp"));
|
||||
|
@ -1516,23 +1516,19 @@ for ($i=0;$i<7;$i++) {
|
|||
&or ("eax",&DWP(0,"edi"));
|
||||
&or ("eax",&DWP(4,"edi"));
|
||||
&or ("eax",&DWP(8,"edi"));
|
||||
&or ("eax",&DWP(12,"edi"));
|
||||
&or ("eax",&DWP(12,"edi")); # ~is_equal(U1,U2)
|
||||
|
||||
&mov ("ebx",&DWP(32*18+0,"esp")); # ~in1infty
|
||||
¬ ("ebx"); # -1/0 -> 0/-1
|
||||
&or ("eax","ebx");
|
||||
&mov ("ebx",&DWP(32*18+4,"esp")); # ~in2infty
|
||||
¬ ("ebx"); # -1/0 -> 0/-1
|
||||
&or ("eax","ebx");
|
||||
&or ("eax",&DWP(32*18+8,"esp")); # ~is_equal(S1,S2)
|
||||
|
||||
# if (~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2))
|
||||
&data_byte(0x3e); # predict taken
|
||||
&jnz (&label("add_proceed")); # is_equal(U1,U2)?
|
||||
|
||||
&mov ("eax",&DWP(32*18+0,"esp"));
|
||||
&and ("eax",&DWP(32*18+4,"esp"));
|
||||
&mov ("ebx",&DWP(32*18+8,"esp"));
|
||||
&jz (&label("add_proceed")); # (in1infty || in2infty)?
|
||||
&test ("ebx","ebx");
|
||||
&jz (&label("add_double")); # is_equal(S1,S2)?
|
||||
|
||||
&mov ("edi",&wparam(0));
|
||||
&xor ("eax","eax");
|
||||
&mov ("ecx",96/4);
|
||||
&data_byte(0xfc,0xf3,0xab); # cld; stosd
|
||||
&jmp (&label("add_done"));
|
||||
&jnz (&label("add_proceed"));
|
||||
|
||||
&set_label("add_double",16);
|
||||
&mov ("esi",&wparam(1));
|
||||
|
@ -1614,34 +1610,34 @@ for ($i=0;$i<7;$i++) {
|
|||
&lea ("edi",&DWP($res_y,"esp"));
|
||||
&call ("_ecp_nistz256_sub"); # p256_sub(res_y, res_y, S2);
|
||||
|
||||
&mov ("ebp",&DWP(32*18+0,"esp")); # !in1infty
|
||||
&mov ("esi",&DWP(32*18+4,"esp")); # !in2infty
|
||||
&mov ("ebp",&DWP(32*18+0,"esp")); # ~in1infty
|
||||
&mov ("esi",&DWP(32*18+4,"esp")); # ~in2infty
|
||||
&mov ("edi",&wparam(0));
|
||||
&mov ("edx","ebp");
|
||||
¬ ("ebp");
|
||||
&and ("edx","esi");
|
||||
&and ("ebp","esi");
|
||||
¬ ("esi");
|
||||
&and ("edx","esi"); # ~in1infty & ~in2infty
|
||||
&and ("ebp","esi"); # in1infty & ~in2infty
|
||||
¬ ("esi"); # in2infty
|
||||
|
||||
########################################
|
||||
# conditional moves
|
||||
for($i=64;$i<96;$i+=4) {
|
||||
&mov ("eax","edx");
|
||||
&mov ("eax","edx"); # ~in1infty & ~in2infty
|
||||
&and ("eax",&DWP($res_x+$i,"esp"));
|
||||
&mov ("ebx","ebp");
|
||||
&mov ("ebx","ebp"); # in1infty & ~in2infty
|
||||
&and ("ebx",&DWP($in2_x+$i,"esp"));
|
||||
&mov ("ecx","esi");
|
||||
&mov ("ecx","esi"); # in2infty
|
||||
&and ("ecx",&DWP($in1_x+$i,"esp"));
|
||||
&or ("eax","ebx");
|
||||
&or ("eax","ecx");
|
||||
&mov (&DWP($i,"edi"),"eax");
|
||||
}
|
||||
for($i=0;$i<64;$i+=4) {
|
||||
&mov ("eax","edx");
|
||||
&mov ("eax","edx"); # ~in1infty & ~in2infty
|
||||
&and ("eax",&DWP($res_x+$i,"esp"));
|
||||
&mov ("ebx","ebp");
|
||||
&mov ("ebx","ebp"); # in1infty & ~in2infty
|
||||
&and ("ebx",&DWP($in2_x+$i,"esp"));
|
||||
&mov ("ecx","esi");
|
||||
&mov ("ecx","esi"); # in2infty
|
||||
&and ("ecx",&DWP($in1_x+$i,"esp"));
|
||||
&or ("eax","ebx");
|
||||
&or ("eax","ecx");
|
||||
|
@ -1668,7 +1664,7 @@ for ($i=0;$i<7;$i++) {
|
|||
|
||||
# above map() describes stack layout with 15 temporary
|
||||
# 256-bit vectors on top, then we take extra words for
|
||||
# !in1infty, !in2infty, and OPENSSL_ia32cap_P copy.
|
||||
# ~in1infty, ~in2infty, and OPENSSL_ia32cap_P copy.
|
||||
&stack_push(8*15+3);
|
||||
if ($sse2) {
|
||||
&call ("_picup_eax");
|
||||
|
@ -1698,7 +1694,7 @@ for ($i=0;$i<7;$i++) {
|
|||
&sub ("eax","ebp");
|
||||
&or ("ebp","eax");
|
||||
&sar ("ebp",31);
|
||||
&mov (&DWP(32*15+0,"esp"),"ebp"); # !in1infty
|
||||
&mov (&DWP(32*15+0,"esp"),"ebp"); # ~in1infty
|
||||
|
||||
&lea ("edi",&DWP($in2_x,"esp"));
|
||||
for($i=0;$i<64;$i+=16) {
|
||||
|
@ -1724,7 +1720,7 @@ for ($i=0;$i<7;$i++) {
|
|||
&lea ("ebp",&DWP($in1_z,"esp"));
|
||||
&sar ("ebx",31);
|
||||
&lea ("edi",&DWP($Z1sqr,"esp"));
|
||||
&mov (&DWP(32*15+4,"esp"),"ebx"); # !in2infty
|
||||
&mov (&DWP(32*15+4,"esp"),"ebx"); # ~in2infty
|
||||
|
||||
&call ("_ecp_nistz256_mul_mont"); # p256_sqr_mont(Z1sqr, in1_z);
|
||||
|
||||
|
@ -1823,14 +1819,14 @@ for ($i=0;$i<7;$i++) {
|
|||
&lea ("edi",&DWP($res_y,"esp"));
|
||||
&call ("_ecp_nistz256_sub"); # p256_sub(res_y, res_y, S2);
|
||||
|
||||
&mov ("ebp",&DWP(32*15+0,"esp")); # !in1infty
|
||||
&mov ("esi",&DWP(32*15+4,"esp")); # !in2infty
|
||||
&mov ("ebp",&DWP(32*15+0,"esp")); # ~in1infty
|
||||
&mov ("esi",&DWP(32*15+4,"esp")); # ~in2infty
|
||||
&mov ("edi",&wparam(0));
|
||||
&mov ("edx","ebp");
|
||||
¬ ("ebp");
|
||||
&and ("edx","esi");
|
||||
&and ("ebp","esi");
|
||||
¬ ("esi");
|
||||
&and ("edx","esi"); # ~in1infty & ~in2infty
|
||||
&and ("ebp","esi"); # in1infty & ~in2infty
|
||||
¬ ("esi"); # in2infty
|
||||
|
||||
########################################
|
||||
# conditional moves
|
||||
|
@ -1848,11 +1844,11 @@ for ($i=0;$i<7;$i++) {
|
|||
&mov (&DWP($i,"edi"),"eax");
|
||||
}
|
||||
for($i=0;$i<64;$i+=4) {
|
||||
&mov ("eax","edx");
|
||||
&mov ("eax","edx"); # ~in1infty & ~in2infty
|
||||
&and ("eax",&DWP($res_x+$i,"esp"));
|
||||
&mov ("ebx","ebp");
|
||||
&mov ("ebx","ebp"); # in1infty & ~in2infty
|
||||
&and ("ebx",&DWP($in2_x+$i,"esp"));
|
||||
&mov ("ecx","esi");
|
||||
&mov ("ecx","esi"); # in2infty
|
||||
&and ("ecx",&DWP($in1_x+$i,"esp"));
|
||||
&or ("eax","ebx");
|
||||
&or ("eax","ecx");
|
||||
|
@ -1863,4 +1859,4 @@ for ($i=0;$i<7;$i++) {
|
|||
|
||||
&asm_finish();
|
||||
|
||||
close STDOUT;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright (c) 2014, Intel Corporation. All Rights Reserved.
|
||||
# Copyright (c) 2015 CloudFlare, Inc.
|
||||
#
|
||||
|
@ -72,7 +72,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
|
|||
$addx = ($1>=12);
|
||||
}
|
||||
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) {
|
||||
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
|
||||
$avx = ($ver>=3.0) + ($ver>=3.01);
|
||||
$addx = ($ver>=3.03);
|
||||
|
@ -1301,7 +1301,7 @@ ecp_nistz256_ord_mul_montx:
|
|||
|
||||
################################# reduction
|
||||
mulx 8*0+128(%r14), $t0, $t1
|
||||
adcx $t0, $acc3 # guranteed to be zero
|
||||
adcx $t0, $acc3 # guaranteed to be zero
|
||||
adox $t1, $acc4
|
||||
|
||||
mulx 8*1+128(%r14), $t0, $t1
|
||||
|
@ -1579,6 +1579,7 @@ $code.=<<___;
|
|||
.type ecp_nistz256_to_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_to_mont:
|
||||
.cfi_startproc
|
||||
___
|
||||
$code.=<<___ if ($addx);
|
||||
mov \$0x80100, %ecx
|
||||
|
@ -1587,6 +1588,7 @@ ___
|
|||
$code.=<<___;
|
||||
lea .LRR(%rip), $b_org
|
||||
jmp .Lmul_mont
|
||||
.cfi_endproc
|
||||
.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
|
||||
|
||||
################################################################################
|
||||
|
@ -2562,6 +2564,7 @@ $code.=<<___;
|
|||
.type ecp_nistz256_scatter_w5,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_scatter_w5:
|
||||
.cfi_startproc
|
||||
lea -3($index,$index,2), $index
|
||||
movdqa 0x00($in_t), %xmm0
|
||||
shl \$5, $index
|
||||
|
@ -2578,6 +2581,7 @@ ecp_nistz256_scatter_w5:
|
|||
movdqa %xmm5, 0x50($val,$index)
|
||||
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
|
||||
|
||||
################################################################################
|
||||
|
@ -2685,6 +2689,7 @@ $code.=<<___;
|
|||
.type ecp_nistz256_scatter_w7,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_scatter_w7:
|
||||
.cfi_startproc
|
||||
movdqu 0x00($in_t), %xmm0
|
||||
shl \$6, $index
|
||||
movdqu 0x10($in_t), %xmm1
|
||||
|
@ -2696,6 +2701,7 @@ ecp_nistz256_scatter_w7:
|
|||
movdqa %xmm3, 0x30($val,$index)
|
||||
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
|
||||
|
||||
################################################################################
|
||||
|
@ -3020,8 +3026,10 @@ $code.=<<___;
|
|||
.type ecp_nistz256_avx2_gather_w7,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_gather_w7:
|
||||
.cfi_startproc
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
|
||||
___
|
||||
}
|
||||
|
@ -3617,29 +3625,19 @@ $code.=<<___;
|
|||
call __ecp_nistz256_sub_from$x # p256_sub(H, U2, U1);
|
||||
|
||||
or $acc5, $acc4 # see if result is zero
|
||||
or $acc0, $acc4
|
||||
or $acc1, $acc4 # !is_equal(U1, U2)
|
||||
|
||||
movq %xmm2, $acc0 # in1infty | in2infty
|
||||
movq %xmm3, $acc1 # !is_equal(S1, S2)
|
||||
|
||||
or $acc0, $acc4
|
||||
or $acc1, $acc4
|
||||
|
||||
# if (!is_equal(U1, U2) | in1infty | in2infty | !is_equal(S1, S2))
|
||||
.byte 0x3e # predict taken
|
||||
jnz .Ladd_proceed$x # is_equal(U1,U2)?
|
||||
movq %xmm2, $acc0
|
||||
movq %xmm3, $acc1
|
||||
test $acc0, $acc0
|
||||
jnz .Ladd_proceed$x # (in1infty || in2infty)?
|
||||
test $acc1, $acc1
|
||||
jz .Ladd_double$x # is_equal(S1,S2)?
|
||||
jnz .Ladd_proceed$x
|
||||
|
||||
movq %xmm0, $r_ptr # restore $r_ptr
|
||||
pxor %xmm0, %xmm0
|
||||
movdqu %xmm0, 0x00($r_ptr)
|
||||
movdqu %xmm0, 0x10($r_ptr)
|
||||
movdqu %xmm0, 0x20($r_ptr)
|
||||
movdqu %xmm0, 0x30($r_ptr)
|
||||
movdqu %xmm0, 0x40($r_ptr)
|
||||
movdqu %xmm0, 0x50($r_ptr)
|
||||
jmp .Ladd_done$x
|
||||
|
||||
.align 32
|
||||
.Ladd_double$x:
|
||||
movq %xmm1, $a_ptr # restore $a_ptr
|
||||
movq %xmm0, $r_ptr # restore $r_ptr
|
||||
|
@ -4738,4 +4736,4 @@ ___
|
|||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -451,7 +451,7 @@ x25519_fe64_tobytes:
|
|||
and $t0,$t0,$t1
|
||||
sldi $a3,$a3,1
|
||||
add $t0,$t0,$t1 # compare to modulus in the same go
|
||||
srdi $a3,$a3,1 # most signifcant bit cleared
|
||||
srdi $a3,$a3,1 # most significant bit cleared
|
||||
|
||||
addc $a0,$a0,$t0
|
||||
addze $a1,$a1
|
||||
|
@ -462,7 +462,7 @@ x25519_fe64_tobytes:
|
|||
sradi $t0,$a3,63 # most significant bit -> mask
|
||||
sldi $a3,$a3,1
|
||||
andc $t0,$t1,$t0
|
||||
srdi $a3,$a3,1 # most signifcant bit cleared
|
||||
srdi $a3,$a3,1 # most significant bit cleared
|
||||
|
||||
subi $rp,$rp,1
|
||||
subfc $a0,$t0,$a0
|
||||
|
@ -821,4 +821,4 @@ ___
|
|||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env perl
|
||||
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -90,7 +90,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
|
|||
$addx = ($1>=12);
|
||||
}
|
||||
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) {
|
||||
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
@ -488,12 +488,14 @@ $code.=<<___;
|
|||
.type x25519_fe64_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
x25519_fe64_eligible:
|
||||
.cfi_startproc
|
||||
mov OPENSSL_ia32cap_P+8(%rip),%ecx
|
||||
xor %eax,%eax
|
||||
and \$0x80100,%ecx
|
||||
cmp \$0x80100,%ecx
|
||||
cmove %ecx,%eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_eligible,.-x25519_fe64_eligible
|
||||
|
||||
.globl x25519_fe64_mul
|
||||
|
@ -722,6 +724,7 @@ x25519_fe64_sqr:
|
|||
.align 32
|
||||
x25519_fe64_mul121666:
|
||||
.Lfe64_mul121666_body:
|
||||
.cfi_startproc
|
||||
mov \$121666,%edx
|
||||
mulx 8*0(%rsi),$acc0,%rcx
|
||||
mulx 8*1(%rsi),$acc1,%rax
|
||||
|
@ -750,6 +753,7 @@ x25519_fe64_mul121666:
|
|||
|
||||
.Lfe64_mul121666_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_mul121666,.-x25519_fe64_mul121666
|
||||
|
||||
.globl x25519_fe64_add
|
||||
|
@ -757,6 +761,7 @@ x25519_fe64_mul121666:
|
|||
.align 32
|
||||
x25519_fe64_add:
|
||||
.Lfe64_add_body:
|
||||
.cfi_startproc
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
|
@ -785,6 +790,7 @@ x25519_fe64_add:
|
|||
|
||||
.Lfe64_add_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_add,.-x25519_fe64_add
|
||||
|
||||
.globl x25519_fe64_sub
|
||||
|
@ -792,6 +798,7 @@ x25519_fe64_add:
|
|||
.align 32
|
||||
x25519_fe64_sub:
|
||||
.Lfe64_sub_body:
|
||||
.cfi_startproc
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
|
@ -820,6 +827,7 @@ x25519_fe64_sub:
|
|||
|
||||
.Lfe64_sub_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_sub,.-x25519_fe64_sub
|
||||
|
||||
.globl x25519_fe64_tobytes
|
||||
|
@ -827,6 +835,7 @@ x25519_fe64_sub:
|
|||
.align 32
|
||||
x25519_fe64_tobytes:
|
||||
.Lfe64_to_body:
|
||||
.cfi_startproc
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
|
@ -862,6 +871,7 @@ x25519_fe64_tobytes:
|
|||
|
||||
.Lfe64_to_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_tobytes,.-x25519_fe64_tobytes
|
||||
___
|
||||
} else {
|
||||
|
@ -870,8 +880,10 @@ $code.=<<___;
|
|||
.type x25519_fe64_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
x25519_fe64_eligible:
|
||||
.cfi_startproc
|
||||
xor %eax,%eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_eligible,.-x25519_fe64_eligible
|
||||
|
||||
.globl x25519_fe64_mul
|
||||
|
@ -887,8 +899,10 @@ x25519_fe64_mul121666:
|
|||
x25519_fe64_add:
|
||||
x25519_fe64_sub:
|
||||
x25519_fe64_tobytes:
|
||||
.cfi_startproc
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size x25519_fe64_mul,.-x25519_fe64_mul
|
||||
___
|
||||
}
|
||||
|
@ -1114,4 +1128,4 @@ ___
|
|||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#if defined(X25519_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
|
||||
|
@ -254,6 +254,7 @@ static void x25519_scalar_mulx(uint8_t out[32], const uint8_t scalar[32],
|
|||
#if defined(X25519_ASM) \
|
||||
|| ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \
|
||||
&& !defined(__sparc__) \
|
||||
&& (!defined(__SIZEOF_LONG__) || (__SIZEOF_LONG__ == 8)) \
|
||||
&& !(defined(__ANDROID__) && !defined(__clang__)) )
|
||||
/*
|
||||
* Base 2^51 implementation. It's virtually no different from reference
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ARCH_32_ARCH_INTRINSICS_H
|
||||
# define HEADER_ARCH_32_ARCH_INTRINSICS_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_32_INTRINSICS_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_ARCH_32_INTRINSICS_H
|
||||
|
||||
#include "internal/constant_time_locl.h"
|
||||
#include "internal/constant_time.h"
|
||||
|
||||
# define ARCH_WORD_BITS 32
|
||||
|
||||
|
@ -24,4 +24,4 @@ static ossl_inline uint64_t widemul(uint32_t a, uint32_t b)
|
|||
return ((uint64_t)a) * b;
|
||||
}
|
||||
|
||||
#endif /* HEADER_ARCH_32_ARCH_INTRINSICS_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_32_INTRINSICS_H */
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ARCH_32_F_IMPL_H
|
||||
# define HEADER_ARCH_32_F_IMPL_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_32_F_IMPL_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_ARCH_32_F_IMPL_H
|
||||
|
||||
# define GF_HEADROOM 2
|
||||
# define LIMB(x) ((x) & ((1 << 28) - 1)), ((x) >> 28)
|
||||
|
@ -57,4 +57,4 @@ void gf_weak_reduce(gf a)
|
|||
a->limb[0] = (a->limb[0] & mask) + tmp;
|
||||
}
|
||||
|
||||
#endif /* HEADER_ARCH_32_F_IMPL_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_32_F_IMPL_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, Inc.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "point_448.h"
|
||||
#include "ed448.h"
|
||||
#include "curve448_lcl.h"
|
||||
#include "curve448_local.h"
|
||||
|
||||
#define COFACTOR 4
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
|||
static const curve448_scalar_t precomputed_scalarmul_adjustment = {
|
||||
{
|
||||
{
|
||||
SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad),
|
||||
SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163)
|
||||
SC_LIMB(0xc873d6d54a7bb0cfULL), SC_LIMB(0xe933d8d723a70aadULL),
|
||||
SC_LIMB(0xbb124b65129c96fdULL), SC_LIMB(0x00000008335dc163ULL)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
#ifndef HEADER_CURVE448_LCL_H
|
||||
# define HEADER_CURVE448_LCL_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_LOCAL_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_LOCAL_H
|
||||
# include "curve448utils.h"
|
||||
|
||||
int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],
|
||||
|
@ -35,4 +35,4 @@ int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
|
|||
int ED448_public_from_private(uint8_t out_public_key[57],
|
||||
const uint8_t private_key[57]);
|
||||
|
||||
#endif /* HEADER_CURVE448_LCL_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015 Cryptography Research, Inc.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -10,8 +10,8 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURVE448UTILS_H
|
||||
# define HEADER_CURVE448UTILS_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448UTILS_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448UTILS_H
|
||||
|
||||
# include <openssl/e_os2.h>
|
||||
|
||||
|
@ -24,7 +24,9 @@
|
|||
*/
|
||||
# ifndef C448_WORD_BITS
|
||||
# if (defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16)) \
|
||||
&& !defined(__sparc__)
|
||||
&& !defined(__sparc__) \
|
||||
&& (!defined(__SIZEOF_LONG__) || (__SIZEOF_LONG__ == 8))
|
||||
|
||||
# define C448_WORD_BITS 64 /* The number of bits in a word */
|
||||
# else
|
||||
# define C448_WORD_BITS 32 /* The number of bits in a word */
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ED448_H
|
||||
# define HEADER_ED448_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_ED448_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_ED448_H
|
||||
|
||||
# include "point_448.h"
|
||||
|
||||
|
@ -192,4 +192,4 @@ c448_error_t c448_ed448_convert_private_key_to_x448(
|
|||
uint8_t x[X448_PRIVATE_BYTES],
|
||||
const uint8_t ed[EDDSA_448_PRIVATE_BYTES]);
|
||||
|
||||
#endif /* HEADER_ED448_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_ED448_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, Inc.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -12,7 +12,7 @@
|
|||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "curve448_lcl.h"
|
||||
#include "curve448_local.h"
|
||||
#include "word.h"
|
||||
#include "ed448.h"
|
||||
#include "internal/numbers.h"
|
||||
|
@ -50,7 +50,12 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
|
|||
const uint8_t *context,
|
||||
size_t context_len)
|
||||
{
|
||||
const char *dom_s = "SigEd448";
|
||||
#ifdef CHARSET_EBCDIC
|
||||
const char dom_s[] = {0x53, 0x69, 0x67, 0x45,
|
||||
0x64, 0x34, 0x34, 0x38, 0x00};
|
||||
#else
|
||||
const char dom_s[] = "SigEd448";
|
||||
#endif
|
||||
uint8_t dom[2];
|
||||
|
||||
if (context_len > UINT8_MAX)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, Inc.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -12,9 +12,9 @@
|
|||
#include "field.h"
|
||||
|
||||
static const gf MODULUS = {
|
||||
FIELD_LITERAL(0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff,
|
||||
0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff,
|
||||
0xffffffffffffff, 0xffffffffffffff)
|
||||
FIELD_LITERAL(0xffffffffffffffULL, 0xffffffffffffffULL, 0xffffffffffffffULL,
|
||||
0xffffffffffffffULL, 0xfffffffffffffeULL, 0xffffffffffffffULL,
|
||||
0xffffffffffffffULL, 0xffffffffffffffULL)
|
||||
};
|
||||
|
||||
/* Serialize to wire format. */
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_FIELD_H
|
||||
# define HEADER_FIELD_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_FIELD_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_FIELD_H
|
||||
|
||||
# include "internal/constant_time_locl.h"
|
||||
# include "internal/constant_time.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include "word.h"
|
||||
|
@ -165,4 +165,4 @@ static ossl_inline void gf_cond_swap(gf x, gf_s * RESTRICT y, mask_t swap)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* HEADER_FIELD_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_FIELD_H */
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_POINT_448_H
|
||||
# define HEADER_POINT_448_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_POINT_448_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_POINT_448_H
|
||||
|
||||
# include "curve448utils.h"
|
||||
# include "field.h"
|
||||
|
@ -298,4 +298,4 @@ void curve448_scalar_destroy(curve448_scalar_t scalar);
|
|||
/* Overwrite point with zeros. */
|
||||
void curve448_point_destroy(curve448_point_t point);
|
||||
|
||||
#endif /* HEADER_POINT_448_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_POINT_448_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, Inc.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -14,24 +14,24 @@
|
|||
#include "word.h"
|
||||
#include "point_448.h"
|
||||
|
||||
static const c448_word_t MONTGOMERY_FACTOR = (c448_word_t) 0x3bd440fae918bc5;
|
||||
static const c448_word_t MONTGOMERY_FACTOR = (c448_word_t) 0x3bd440fae918bc5ULL;
|
||||
static const curve448_scalar_t sc_p = {
|
||||
{
|
||||
{
|
||||
SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x216cc2728dc58f55),
|
||||
SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xffffffff7cca23e9),
|
||||
SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff),
|
||||
SC_LIMB(0x3fffffffffffffff)
|
||||
SC_LIMB(0x2378c292ab5844f3ULL), SC_LIMB(0x216cc2728dc58f55ULL),
|
||||
SC_LIMB(0xc44edb49aed63690ULL), SC_LIMB(0xffffffff7cca23e9ULL),
|
||||
SC_LIMB(0xffffffffffffffffULL), SC_LIMB(0xffffffffffffffffULL),
|
||||
SC_LIMB(0x3fffffffffffffffULL)
|
||||
}
|
||||
}
|
||||
}, sc_r2 = {
|
||||
{
|
||||
{
|
||||
|
||||
SC_LIMB(0xe3539257049b9b60), SC_LIMB(0x7af32c4bc1b195d9),
|
||||
SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0xae17cf725ee4d838),
|
||||
SC_LIMB(0x1a9cc14ba3c47c44), SC_LIMB(0x2052bcb7e4d070af),
|
||||
SC_LIMB(0x3402a939f823b729)
|
||||
SC_LIMB(0xe3539257049b9b60ULL), SC_LIMB(0x7af32c4bc1b195d9ULL),
|
||||
SC_LIMB(0x0d66de2388ea1859ULL), SC_LIMB(0xae17cf725ee4d838ULL),
|
||||
SC_LIMB(0x1a9cc14ba3c47c44ULL), SC_LIMB(0x2052bcb7e4d070afULL),
|
||||
SC_LIMB(0x3402a939f823b729ULL)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* Originally written by Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_WORD_H
|
||||
# define HEADER_WORD_H
|
||||
#ifndef OSSL_CRYPTO_EC_CURVE448_WORD_H
|
||||
# define OSSL_CRYPTO_EC_CURVE448_WORD_H
|
||||
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
@ -78,4 +78,4 @@ static ossl_inline mask_t bool_to_mask(c448_bool_t m)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HEADER_WORD_H */
|
||||
#endif /* OSSL_CRYPTO_EC_CURVE448_WORD_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
|
@ -237,7 +237,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
|||
BN_CTX *ctx)
|
||||
{
|
||||
point_conversion_form_t form;
|
||||
int y_bit;
|
||||
int y_bit, m;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x, *y, *yxi;
|
||||
size_t field_len, enc_len;
|
||||
|
@ -247,9 +247,21 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
|||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
form = buf[0];
|
||||
y_bit = form & 1;
|
||||
form = form & ~1U;
|
||||
|
||||
/*
|
||||
* The first octet is the point converison octet PC, see X9.62, page 4
|
||||
* and section 4.4.2. It must be:
|
||||
* 0x00 for the point at infinity
|
||||
* 0x02 or 0x03 for compressed form
|
||||
* 0x04 for uncompressed form
|
||||
* 0x06 or 0x07 for hybrid form.
|
||||
* For compressed or hybrid forms, we store the last bit of buf[0] as
|
||||
* y_bit and clear it from buf[0] so as to obtain a POINT_CONVERSION_*.
|
||||
* We error if buf[0] contains any but the above values.
|
||||
*/
|
||||
y_bit = buf[0] & 1;
|
||||
form = buf[0] & ~1U;
|
||||
|
||||
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
|
||||
&& (form != POINT_CONVERSION_UNCOMPRESSED)
|
||||
&& (form != POINT_CONVERSION_HYBRID)) {
|
||||
|
@ -261,6 +273,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
|||
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);
|
||||
|
@ -270,7 +283,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
|||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
m = EC_GROUP_get_degree(group);
|
||||
field_len = (m + 7) / 8;
|
||||
enc_len =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
|
@ -295,7 +309,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_ucmp(x, group->field) >= 0) {
|
||||
if (BN_num_bits(x) > m) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
|
@ -306,16 +320,28 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
|||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
if (BN_num_bits(y) > m) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
if (form == POINT_CONVERSION_HYBRID) {
|
||||
if (!group->meth->field_div(group, yxi, y, x, ctx))
|
||||
goto err;
|
||||
if (y_bit != BN_is_odd(yxi)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
/*
|
||||
* Check that the form in the encoding was set correctly
|
||||
* according to X9.62 4.4.2.a, 4(c), see also first paragraph
|
||||
* of X9.62, 4.4.1.b.
|
||||
*/
|
||||
if (BN_is_zero(x)) {
|
||||
if (y_bit != 0) {
|
||||
ECerr(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);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
|
@ -204,8 +204,7 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -14,16 +14,16 @@
|
|||
#include <openssl/bn.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.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, EC_KEY *ec_key)
|
||||
static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
|
||||
{
|
||||
const EC_GROUP *group;
|
||||
int nid;
|
||||
|
@ -35,7 +35,14 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
|||
&& (nid = EC_GROUP_get_curve_name(group)))
|
||||
/* we have a 'named curve' => just set the OID */
|
||||
{
|
||||
*ppval = OBJ_nid2obj(nid);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
*ppval = asn1obj;
|
||||
*pptype = V_ASN1_OBJECT;
|
||||
} else { /* explicit parameters */
|
||||
|
||||
|
@ -43,7 +50,17 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
|||
pstr = ASN1_STRING_new();
|
||||
if (pstr == NULL)
|
||||
return 0;
|
||||
pstr->length = i2d_ECParameters(ec_key, &pstr->data);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
if (pstr->length <= 0) {
|
||||
ASN1_STRING_free(pstr);
|
||||
ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
|
||||
|
@ -57,7 +74,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
|||
|
||||
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec_key = pkey->pkey.ec;
|
||||
const EC_KEY *ec_key = pkey->pkey.ec;
|
||||
void *pval = NULL;
|
||||
int ptype;
|
||||
unsigned char *penc = NULL, *p;
|
||||
|
@ -504,7 +521,12 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
|||
#endif
|
||||
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
*(int *)arg2 = NID_sha256;
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
|
||||
/* For SM2, the only valid digest-alg is SM3 */
|
||||
*(int *)arg2 = NID_sm3;
|
||||
} else {
|
||||
*(int *)arg2 = NID_sha256;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
|
|
143
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_asn1.c
vendored
143
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_asn1.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/objects.h>
|
||||
|
@ -137,6 +137,12 @@ struct ec_parameters_st {
|
|||
ASN1_INTEGER *cofactor;
|
||||
} /* ECPARAMETERS */ ;
|
||||
|
||||
typedef enum {
|
||||
ECPKPARAMETERS_TYPE_NAMED = 0,
|
||||
ECPKPARAMETERS_TYPE_EXPLICIT,
|
||||
ECPKPARAMETERS_TYPE_IMPLICIT
|
||||
} ecpk_parameters_type_t;
|
||||
|
||||
struct ecpk_parameters_st {
|
||||
int type;
|
||||
union {
|
||||
|
@ -446,6 +452,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
|||
unsigned char *buffer = NULL;
|
||||
const EC_POINT *point = NULL;
|
||||
point_conversion_form_t form;
|
||||
ASN1_INTEGER *orig;
|
||||
|
||||
if (params == NULL) {
|
||||
if ((ret = ECPARAMETERS_new()) == NULL) {
|
||||
|
@ -496,8 +503,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
|||
ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
|
||||
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);
|
||||
goto err;
|
||||
}
|
||||
|
@ -505,8 +513,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
|||
/* set the cofactor (optional) */
|
||||
tmp = EC_GROUP_get0_cofactor(group);
|
||||
if (tmp != NULL) {
|
||||
ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
|
||||
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);
|
||||
goto err;
|
||||
}
|
||||
|
@ -532,9 +541,10 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
|
|||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (ret->type == 0)
|
||||
if (ret->type == ECPKPARAMETERS_TYPE_NAMED)
|
||||
ASN1_OBJECT_free(ret->value.named_curve);
|
||||
else if (ret->type == 1 && ret->value.parameters)
|
||||
else if (ret->type == ECPKPARAMETERS_TYPE_EXPLICIT
|
||||
&& ret->value.parameters != NULL)
|
||||
ECPARAMETERS_free(ret->value.parameters);
|
||||
}
|
||||
|
||||
|
@ -544,15 +554,22 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
|
|||
*/
|
||||
tmp = EC_GROUP_get_curve_name(group);
|
||||
if (tmp) {
|
||||
ret->type = 0;
|
||||
if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
|
||||
ASN1_OBJECT *asn1obj = OBJ_nid2obj(tmp);
|
||||
|
||||
if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
|
||||
ASN1_OBJECT_free(asn1obj);
|
||||
ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID);
|
||||
ok = 0;
|
||||
} else {
|
||||
ret->type = ECPKPARAMETERS_TYPE_NAMED;
|
||||
ret->value.named_curve = asn1obj;
|
||||
}
|
||||
} else
|
||||
/* we don't know the nid => ERROR */
|
||||
ok = 0;
|
||||
} else {
|
||||
/* use the ECPARAMETERS structure */
|
||||
ret->type = 1;
|
||||
ret->type = ECPKPARAMETERS_TYPE_EXPLICIT;
|
||||
if ((ret->value.parameters =
|
||||
EC_GROUP_get_ecparameters(group, NULL)) == NULL)
|
||||
ok = 0;
|
||||
|
@ -568,10 +585,12 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
|
|||
EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
||||
{
|
||||
int ok = 0, tmp;
|
||||
EC_GROUP *ret = NULL;
|
||||
EC_GROUP *ret = NULL, *dup = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
long field_bits;
|
||||
int curve_name = NID_undef;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
if (!params->fieldID || !params->fieldID->fieldType ||
|
||||
!params->fieldID->p.ptr) {
|
||||
|
@ -742,7 +761,10 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
|||
ret->seed_len = params->curve->seed->length;
|
||||
}
|
||||
|
||||
if (!params->order || !params->base || !params->base->data) {
|
||||
if (params->order == NULL
|
||||
|| params->base == NULL
|
||||
|| params->base->data == NULL
|
||||
|| params->base->length == 0) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
@ -789,18 +811,93 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the explicit parameters group just created matches one of the
|
||||
* built-in curves.
|
||||
*
|
||||
* We create a copy of the group just built, so that we can remove optional
|
||||
* fields for the lookup: we do this to avoid the possibility that one of
|
||||
* the optional parameters is used to force the library into using a less
|
||||
* performant and less secure EC_METHOD instead of the specialized one.
|
||||
* In any case, `seed` is not really used in any computation, while a
|
||||
* cofactor different from the one in the built-in table is just
|
||||
* mathematically wrong anyway and should not be used.
|
||||
*/
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, 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);
|
||||
goto err;
|
||||
}
|
||||
if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
|
||||
/*
|
||||
* The input explicit parameters successfully matched one of the
|
||||
* built-in curves: often for built-in curves we have specialized
|
||||
* methods with better performance and hardening.
|
||||
*
|
||||
* In this case we replace the `EC_GROUP` created through explicit
|
||||
* parameters with one created from a named group.
|
||||
*/
|
||||
EC_GROUP *named_group = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
/*
|
||||
* NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
|
||||
* the same curve, we prefer the SECP nid when matching explicit
|
||||
* parameters as that is associated with a specialized EC_METHOD.
|
||||
*/
|
||||
if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
|
||||
curve_name = NID_secp224r1;
|
||||
#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
|
||||
|
||||
if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
EC_GROUP_free(ret);
|
||||
ret = named_group;
|
||||
|
||||
/*
|
||||
* Set the flag so that EC_GROUPs created from explicit parameters are
|
||||
* serialized using explicit parameters by default.
|
||||
*/
|
||||
EC_GROUP_set_asn1_flag(ret, 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 (params->curve->seed == NULL) {
|
||||
if (EC_GROUP_set_seed(ret, NULL, 0) != 1)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (!ok) {
|
||||
EC_GROUP_clear_free(ret);
|
||||
EC_GROUP_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
EC_GROUP_free(dup);
|
||||
|
||||
BN_free(p);
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
EC_POINT_free(point);
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -814,7 +911,8 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (params->type == 0) { /* the curve is given by an OID */
|
||||
if (params->type == ECPKPARAMETERS_TYPE_NAMED) {
|
||||
/* 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,
|
||||
|
@ -822,15 +920,16 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
|
|||
return NULL;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
|
||||
} else if (params->type == 1) { /* the parameters are given by a
|
||||
* ECPARAMETERS structure */
|
||||
} else if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) {
|
||||
/* 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);
|
||||
return NULL;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
|
||||
} else if (params->type == 2) { /* implicitlyCA */
|
||||
} else if (params->type == ECPKPARAMETERS_TYPE_IMPLICIT) {
|
||||
/* implicit parameters inherited from CA - unsupported */
|
||||
return NULL;
|
||||
} else {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
|
||||
|
@ -860,8 +959,11 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT)
|
||||
group->decoded_from_explicit_params = 1;
|
||||
|
||||
if (a) {
|
||||
EC_GROUP_clear_free(*a);
|
||||
EC_GROUP_free(*a);
|
||||
*a = group;
|
||||
}
|
||||
|
||||
|
@ -909,8 +1011,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
|||
ret = *a;
|
||||
|
||||
if (priv_key->parameters) {
|
||||
EC_GROUP_clear_free(ret->group);
|
||||
EC_GROUP_free(ret->group);
|
||||
ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
|
||||
if (ret->group != NULL
|
||||
&& priv_key->parameters->type == ECPKPARAMETERS_TYPE_EXPLICIT)
|
||||
ret->group->decoded_from_explicit_params = 1;
|
||||
}
|
||||
|
||||
if (ret->group == NULL) {
|
||||
|
@ -1217,5 +1322,7 @@ int ECDSA_size(const EC_KEY *r)
|
|||
i = i2d_ASN1_INTEGER(&bs, NULL);
|
||||
i += i; /* r and s */
|
||||
ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
|
|
116
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_curve.c
vendored
116
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_curve.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2019 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
|
||||
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
@ -3197,3 +3197,115 @@ int EC_curve_nist2nid(const char *name)
|
|||
}
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
#define NUM_BN_FIELDS 6
|
||||
/*
|
||||
* Validates EC domain parameter data for known named curves.
|
||||
* This can be used when a curve is loaded explicitly (without a curve
|
||||
* name) or to validate that domain parameters have not been modified.
|
||||
*
|
||||
* Returns: The nid associated with the found named curve, or NID_undef
|
||||
* if not found. If there was an error it returns -1.
|
||||
*/
|
||||
int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
int ret = -1, nid, len, field_type, param_len;
|
||||
size_t i, seed_len;
|
||||
const unsigned char *seed, *params_seed, *params;
|
||||
unsigned char *param_bytes = NULL;
|
||||
const EC_CURVE_DATA *data;
|
||||
const EC_POINT *generator = NULL;
|
||||
const EC_METHOD *meth;
|
||||
const BIGNUM *cofactor = NULL;
|
||||
/* An array of BIGNUMs for (p, a, b, x, y, order) */
|
||||
BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
meth = EC_GROUP_method_of(group);
|
||||
if (meth == NULL)
|
||||
return -1;
|
||||
/* Use the optional named curve nid as a search field */
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
field_type = EC_METHOD_get_field_type(meth);
|
||||
seed_len = EC_GROUP_get_seed_len(group);
|
||||
seed = EC_GROUP_get0_seed(group);
|
||||
cofactor = EC_GROUP_get0_cofactor(group);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
/*
|
||||
* The built-in curves contains data fields (p, a, b, x, y, order) that are
|
||||
* all zero-padded to be the same size. The size of the padding is
|
||||
* determined by either the number of bytes in the field modulus (p) or the
|
||||
* EC group order, whichever is larger.
|
||||
*/
|
||||
param_len = BN_num_bytes(group->order);
|
||||
len = BN_num_bytes(group->field);
|
||||
if (len > param_len)
|
||||
param_len = len;
|
||||
|
||||
/* Allocate space to store the padded data for (p, a, b, x, y, order) */
|
||||
param_bytes = OPENSSL_malloc(param_len * NUM_BN_FIELDS);
|
||||
if (param_bytes == NULL)
|
||||
goto end;
|
||||
|
||||
/* Create the bignums */
|
||||
for (i = 0; i < NUM_BN_FIELDS; ++i) {
|
||||
if ((bn[i] = BN_CTX_get(ctx)) == NULL)
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
* Fill in the bn array with the same values as the internal curves
|
||||
* i.e. the values are p, a, b, x, y, order.
|
||||
*/
|
||||
/* Get p, a & b */
|
||||
if (!(EC_GROUP_get_curve(group, bn[0], bn[1], bn[2], ctx)
|
||||
&& ((generator = EC_GROUP_get0_generator(group)) != NULL)
|
||||
/* Get x & y */
|
||||
&& EC_POINT_get_affine_coordinates(group, generator, bn[3], bn[4], ctx)
|
||||
/* Get order */
|
||||
&& EC_GROUP_get_order(group, bn[5], ctx)))
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Convert the bignum array to bytes that are joined together to form
|
||||
* a single buffer that contains data for all fields.
|
||||
* (p, a, b, x, y, order) are all zero padded to be the same size.
|
||||
*/
|
||||
for (i = 0; i < NUM_BN_FIELDS; ++i) {
|
||||
if (BN_bn2binpad(bn[i], ¶m_bytes[i*param_len], param_len) <= 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < curve_list_length; i++) {
|
||||
const ec_list_element curve = curve_list[i];
|
||||
|
||||
data = curve.data;
|
||||
/* Get the raw order byte data */
|
||||
params_seed = (const unsigned char *)(data + 1); /* skip header */
|
||||
params = params_seed + data->seed_len;
|
||||
|
||||
/* Look for unique fields in the fixed curve data */
|
||||
if (data->field_type == field_type
|
||||
&& param_len == data->param_len
|
||||
&& (nid <= 0 || nid == curve.nid)
|
||||
/* check the optional cofactor (ignore if its zero) */
|
||||
&& (BN_is_zero(cofactor)
|
||||
|| BN_is_word(cofactor, (const BN_ULONG)curve.data->cofactor))
|
||||
/* Check the optional seed (ignore if its not set) */
|
||||
&& (data->seed_len == 0 || seed_len == 0
|
||||
|| ((size_t)data->seed_len == seed_len
|
||||
&& memcmp(params_seed, seed, seed_len) == 0))
|
||||
/* Check that the groups params match the built-in curve params */
|
||||
&& memcmp(param_bytes, params, param_len * NUM_BN_FIELDS)
|
||||
== 0) {
|
||||
ret = curve.nid;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* Gets here if the group was not found */
|
||||
ret = NID_undef;
|
||||
end:
|
||||
OPENSSL_free(param_bytes);
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -341,6 +341,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
|
|||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_POST_FAILURE), "ladder post failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_PRE_FAILURE), "ladder pre failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_STEP_FAILURE), "ladder step failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_OID), "missing OID"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY), "missing private key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NEED_NEW_SETUP_VALUES),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -10,10 +10,11 @@
|
|||
|
||||
#include "internal/cryptlib.h"
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "crypto/bn.h"
|
||||
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
{
|
||||
|
@ -416,17 +417,86 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
|
|||
|
||||
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
|
||||
{
|
||||
int fixed_top;
|
||||
const BIGNUM *order = NULL;
|
||||
BIGNUM *tmp_key = NULL;
|
||||
|
||||
if (key->group == NULL || key->group->meth == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Not only should key->group be set, but it should also be in a valid
|
||||
* fully initialized state.
|
||||
*
|
||||
* Specifically, to operate in constant time, we need that the group order
|
||||
* is set, as we use its length as the fixed public size of any scalar used
|
||||
* as an EC private key.
|
||||
*/
|
||||
order = EC_GROUP_get0_order(key->group);
|
||||
if (order == NULL || BN_is_zero(order))
|
||||
return 0; /* This should never happen */
|
||||
|
||||
if (key->group->meth->set_private != NULL
|
||||
&& key->group->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
if (key->meth->set_private != NULL
|
||||
&& key->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We should never leak the bit length of the secret scalar in the key,
|
||||
* so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
|
||||
* holding the secret scalar.
|
||||
*
|
||||
* This is important also because `BN_dup()` (and `BN_copy()`) do not
|
||||
* propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
|
||||
* this brings an extra risk of inadvertently losing the flag, even when
|
||||
* the caller specifically set it.
|
||||
*
|
||||
* The propagation has been turned on and off a few times in the past
|
||||
* years because in some conditions has shown unintended consequences in
|
||||
* some code paths, so at the moment we can't fix this in the BN layer.
|
||||
*
|
||||
* In `EC_KEY_set_private_key()` we can work around the propagation by
|
||||
* manually setting the flag after `BN_dup()` as we know for sure that
|
||||
* inside the EC module the `BN_FLG_CONSTTIME` is always treated
|
||||
* correctly and should not generate unintended consequences.
|
||||
*
|
||||
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
|
||||
* to preallocate the BIGNUM internal buffer to a fixed public size big
|
||||
* enough that operations performed during the processing never trigger
|
||||
* a realloc which would leak the size of the scalar through memory
|
||||
* accesses.
|
||||
*
|
||||
* Fixed Length
|
||||
* ------------
|
||||
*
|
||||
* The order of the large prime subgroup of the curve is our choice for
|
||||
* a fixed public size, as that is generally the upper bound for
|
||||
* generating a private key in EC cryptosystems and should fit all valid
|
||||
* secret scalars.
|
||||
*
|
||||
* For preallocating the BIGNUM storage we look at the number of "words"
|
||||
* required for the internal representation of the order, and we
|
||||
* preallocate 2 extra "words" in case any of the subsequent processing
|
||||
* might temporarily overflow the order length.
|
||||
*/
|
||||
tmp_key = BN_dup(priv_key);
|
||||
if (tmp_key == NULL)
|
||||
return 0;
|
||||
|
||||
BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
|
||||
|
||||
fixed_top = bn_get_top(order) + 2;
|
||||
if (bn_wexpand(tmp_key, fixed_top) == NULL) {
|
||||
BN_clear_free(tmp_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_clear_free(key->priv_key);
|
||||
key->priv_key = BN_dup(priv_key);
|
||||
return (key->priv_key == NULL) ? 0 : 1;
|
||||
key->priv_key = tmp_key;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
|
||||
|
@ -494,6 +564,13 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags)
|
|||
key->flags &= ~flags;
|
||||
}
|
||||
|
||||
int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
|
||||
{
|
||||
if (key == NULL || key->group == NULL)
|
||||
return -1;
|
||||
return key->group->decoded_from_explicit_params;
|
||||
}
|
||||
|
||||
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
|
||||
unsigned char **pbuf, BN_CTX *ctx)
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <openssl/ec.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
|
||||
static const EC_KEY_METHOD openssl_ec_key_method = {
|
||||
|
|
119
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lib.c
vendored
119
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lib.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 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
|
||||
|
@ -13,7 +13,7 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
|
@ -211,6 +211,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
|||
|
||||
dest->asn1_flag = src->asn1_flag;
|
||||
dest->asn1_form = src->asn1_form;
|
||||
dest->decoded_from_explicit_params = src->decoded_from_explicit_params;
|
||||
|
||||
if (src->seed) {
|
||||
OPENSSL_free(dest->seed);
|
||||
|
@ -265,6 +266,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
|
|||
|
||||
static int ec_precompute_mont_data(EC_GROUP *);
|
||||
|
||||
/*-
|
||||
* Try computing cofactor from the generator order (n) and field cardinality (q).
|
||||
* This works for all curves of cryptographic interest.
|
||||
*
|
||||
* Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
|
||||
* h_min = (q + 1 - 2*sqrt(q))/n
|
||||
* h_max = (q + 1 + 2*sqrt(q))/n
|
||||
* h_max - h_min = 4*sqrt(q)/n
|
||||
* So if n > 4*sqrt(q) holds, there is only one possible value for h:
|
||||
* h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
|
||||
*
|
||||
* Otherwise, zero cofactor and return success.
|
||||
*/
|
||||
static int ec_guess_cofactor(EC_GROUP *group) {
|
||||
int ret = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *q = NULL;
|
||||
|
||||
/*-
|
||||
* If the cofactor is too large, we cannot guess it.
|
||||
* The RHS of below is a strict overestimate of lg(4 * sqrt(q))
|
||||
*/
|
||||
if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) {
|
||||
/* default to 0 */
|
||||
BN_zero(group->cofactor);
|
||||
/* return success */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((q = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* set q = 2**m for binary fields; q = p otherwise */
|
||||
if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
|
||||
BN_zero(q);
|
||||
if (!BN_set_bit(q, BN_num_bits(group->field) - 1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_copy(q, group->field))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
|
||||
if (!BN_rshift1(group->cofactor, group->order) /* n/2 */
|
||||
|| !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */
|
||||
/* q + 1 + n/2 */
|
||||
|| !BN_add(group->cofactor, group->cofactor, BN_value_one())
|
||||
/* (q + 1 + n/2)/n */
|
||||
|| !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
||||
const BIGNUM *order, const BIGNUM *cofactor)
|
||||
{
|
||||
|
@ -273,6 +335,34 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
|||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* - require order >= 1
|
||||
* - enforce upper bound due to Hasse thm: order can be no more than one bit
|
||||
* longer than field cardinality
|
||||
*/
|
||||
if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
|
||||
|| BN_num_bits(order) > BN_num_bits(group->field) + 1) {
|
||||
ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Unfortunately the cofactor is an optional field in many standards.
|
||||
* Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
|
||||
* So accept cofactor == NULL or cofactor >= 0.
|
||||
*/
|
||||
if (cofactor != NULL && BN_is_negative(cofactor)) {
|
||||
ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (group->generator == NULL) {
|
||||
group->generator = EC_POINT_new(group);
|
||||
if (group->generator == NULL)
|
||||
|
@ -281,17 +371,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
|||
if (!EC_POINT_copy(group->generator, generator))
|
||||
return 0;
|
||||
|
||||
if (order != NULL) {
|
||||
if (!BN_copy(group->order, order))
|
||||
return 0;
|
||||
} else
|
||||
BN_zero(group->order);
|
||||
if (!BN_copy(group->order, order))
|
||||
return 0;
|
||||
|
||||
if (cofactor != NULL) {
|
||||
/* Either take the provided positive cofactor, or try to compute it */
|
||||
if (cofactor != NULL && !BN_is_zero(cofactor)) {
|
||||
if (!BN_copy(group->cofactor, cofactor))
|
||||
return 0;
|
||||
} else
|
||||
} else if (!ec_guess_cofactor(group)) {
|
||||
BN_zero(group->cofactor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some groups have an order with
|
||||
|
@ -918,14 +1008,14 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
size_t i = 0;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
|
||||
if ((scalar == NULL) && (num == 0)) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
if (!ec_point_is_compat(r, group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (scalar == NULL && num == 0)
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_point_is_compat(points[i], group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
|
@ -1074,8 +1164,7 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 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
|
||||
|
@ -14,7 +14,7 @@
|
|||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/ec_int.h"
|
||||
#include "crypto/ec.h"
|
||||
|
||||
#if defined(__SUNPRO_C)
|
||||
# if __SUNPRO_C >= 0x520
|
||||
|
@ -154,7 +154,7 @@ struct ec_method_st {
|
|||
int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
/*-
|
||||
* 'field_inv' computes the multipicative inverse of a in the field,
|
||||
* 'field_inv' computes the multiplicative inverse of a in the field,
|
||||
* storing the result in r.
|
||||
*
|
||||
* If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error.
|
||||
|
@ -209,6 +209,8 @@ struct ec_group_st {
|
|||
BIGNUM *order, *cofactor;
|
||||
int curve_name; /* optional NID for named curve */
|
||||
int asn1_flag; /* flag to control the asn1 encoding */
|
||||
int decoded_from_explicit_params; /* set if decoded from explicit
|
||||
* curve parameters encoding */
|
||||
point_conversion_form_t asn1_form;
|
||||
unsigned char *seed; /* optional seed for parameters (appears in
|
||||
* ASN1) */
|
||||
|
@ -595,6 +597,8 @@ 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);
|
||||
|
||||
int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
|
||||
|
||||
/* EC_METHOD definitions */
|
||||
|
||||
struct ec_key_method_st {
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 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
|
||||
|
@ -12,8 +12,8 @@
|
|||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "ec_local.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
/*
|
||||
|
@ -260,17 +260,10 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*-
|
||||
* 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
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
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);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Initialize the Montgomery ladder */
|
||||
|
@ -378,7 +371,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
|||
|
||||
err:
|
||||
EC_POINT_free(p);
|
||||
EC_POINT_free(s);
|
||||
EC_POINT_clear_free(s);
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
|
@ -441,7 +434,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
* scalar multiplication implementation based on a Montgomery ladder,
|
||||
* with various timing attack defenses.
|
||||
*/
|
||||
if ((scalar != NULL) && (num == 0)) {
|
||||
if ((scalar != group->order) && (scalar != NULL) && (num == 0)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GeneratorPoint: this
|
||||
* codepath is reached most prominently by (ephemeral) key
|
||||
|
@ -452,7 +445,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
*/
|
||||
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
|
||||
}
|
||||
if ((scalar == NULL) && (num == 1)) {
|
||||
if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * VariablePoint: this
|
||||
* codepath is reached most prominently by the second half of ECDH,
|
||||
|
@ -747,6 +740,20 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
if (r_is_at_infinity) {
|
||||
if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* 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
|
||||
* 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);
|
||||
goto err;
|
||||
}
|
||||
|
||||
r_is_at_infinity = 0;
|
||||
} else {
|
||||
if (!EC_POINT_add
|
||||
|
@ -948,8 +955,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_ec_pre_comp_free(pre_comp);
|
||||
if (points) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
|
||||
const BIGNUM *x, int y_bit, BN_CTX *ctx)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -12,9 +12,9 @@
|
|||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "crypto/evp.h"
|
||||
|
||||
/* EC pkey context structure */
|
||||
|
||||
|
@ -323,7 +323,11 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_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);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
|
@ -39,13 +39,13 @@ EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
|
|||
EC_POINT *ret;
|
||||
|
||||
if ((buf_len = BN_num_bytes(bn)) == 0)
|
||||
return NULL;
|
||||
buf_len = 1;
|
||||
if ((buf = OPENSSL_malloc(buf_len)) == NULL) {
|
||||
ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!BN_bn2bin(bn, buf)) {
|
||||
if (!BN_bn2binpad(bn, buf, buf_len)) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
/* Key derivation function from X9.63/SECG */
|
||||
/* Way more than we will ever need */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2019 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
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include <openssl/bn.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh)
|
||||
|
@ -58,7 +58,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
|||
|
||||
priv_key = EC_KEY_get0_private_key(ecdh);
|
||||
if (priv_key == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_MISSING_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -112,9 +112,8 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(tmp);
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
EC_POINT_clear_free(tmp);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(buf);
|
||||
return ret;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -11,8 +11,8 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen,
|
||||
|
@ -41,11 +41,16 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
|||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
int order_bits;
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, 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);
|
||||
|
@ -83,8 +88,7 @@ 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,
|
||||
EC_KEY_get0_private_key(eckey),
|
||||
if (!BN_generate_dsa_nonce(k, order, priv_key,
|
||||
dgst, dlen, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
|
@ -162,10 +166,14 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
|||
group = EC_KEY_get0_group(eckey);
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
|
||||
if (group == NULL || priv_key == NULL) {
|
||||
if (group == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (priv_key == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, 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);
|
||||
|
@ -301,7 +309,7 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
|||
goto err;
|
||||
ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
|
||||
err:
|
||||
OPENSSL_clear_free(der, derlen);
|
||||
OPENSSL_free(der);
|
||||
ECDSA_SIG_free(s);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*-
|
||||
|
@ -23,7 +23,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);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -39,5 +39,5 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
|
|||
return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
|
||||
eckey);
|
||||
ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_nist_method(void)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2010-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -38,7 +38,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
|||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
# include "ec_local.h"
|
||||
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
|
@ -72,6 +72,7 @@ typedef uint64_t u64;
|
|||
*/
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef uint64_t limb_aX __attribute((__aligned__(1)));
|
||||
typedef uint128_t widelimb;
|
||||
|
||||
typedef limb felem[4];
|
||||
|
@ -307,10 +308,10 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
|
|||
*/
|
||||
static void bin28_to_felem(felem out, const u8 in[28])
|
||||
{
|
||||
out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const uint64_t *)(in+20))) >> 8;
|
||||
out[0] = *((const limb *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const limb_aX *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const limb_aX *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const limb_aX *)(in + 20))) >> 8;
|
||||
}
|
||||
|
||||
static void felem_to_bin28(u8 out[28], const felem in)
|
||||
|
@ -324,34 +325,21 @@ static void felem_to_bin28(u8 out[28], const felem in)
|
|||
}
|
||||
}
|
||||
|
||||
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
|
||||
static void flip_endian(u8 *out, const u8 *in, unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; ++i)
|
||||
out[i] = in[len - 1 - i];
|
||||
}
|
||||
|
||||
/* From OpenSSL BIGNUM to internal representation */
|
||||
static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
{
|
||||
felem_bytearray b_in;
|
||||
felem_bytearray b_out;
|
||||
unsigned num_bytes;
|
||||
int num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof(b_out));
|
||||
num_bytes = BN_num_bytes(bn);
|
||||
if (num_bytes > sizeof(b_out)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
if (BN_is_negative(bn)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
num_bytes = BN_bn2bin(bn, b_in);
|
||||
flip_endian(b_out, b_in, num_bytes);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
bin28_to_felem(out, b_out);
|
||||
return 1;
|
||||
}
|
||||
|
@ -359,10 +347,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
|||
/* From internal representation to OpenSSL BIGNUM */
|
||||
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
|
||||
{
|
||||
felem_bytearray b_in, b_out;
|
||||
felem_to_bin28(b_in, in);
|
||||
flip_endian(b_out, b_in, sizeof(b_out));
|
||||
return BN_bin2bn(b_out, sizeof(b_out), out);
|
||||
felem_bytearray b_out;
|
||||
felem_to_bin28(b_out, in);
|
||||
return BN_lebin2bn(b_out, sizeof(b_out), out);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -921,6 +908,7 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
|
||||
widefelem tmp, tmp2;
|
||||
limb z1_is_zero, z2_is_zero, x_equal, y_equal;
|
||||
limb points_equal;
|
||||
|
||||
if (!mixed) {
|
||||
/* ftmp2 = z2^2 */
|
||||
|
@ -977,15 +965,41 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
felem_reduce(ftmp, tmp);
|
||||
|
||||
/*
|
||||
* the formulae are incorrect if the points are equal so we check for
|
||||
* this and do doubling if this happens
|
||||
* The formulae are incorrect if the points are equal, in affine coordinates
|
||||
* (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
|
||||
* happens.
|
||||
*
|
||||
* We use bitwise operations to avoid potential side-channels introduced by
|
||||
* the short-circuiting behaviour of boolean operators.
|
||||
*/
|
||||
x_equal = felem_is_zero(ftmp);
|
||||
y_equal = felem_is_zero(ftmp3);
|
||||
/*
|
||||
* The special case of either point being the point at infinity (z1 and/or
|
||||
* z2 are zero), is handled separately later on in this function, so we
|
||||
* avoid jumping to point_double here in those special cases.
|
||||
*/
|
||||
z1_is_zero = felem_is_zero(z1);
|
||||
z2_is_zero = felem_is_zero(z2);
|
||||
/* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
|
||||
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
|
||||
|
||||
/*
|
||||
* Compared to `ecp_nistp256.c` and `ecp_nistp521.c`, in this
|
||||
* specific implementation `felem_is_zero()` returns truth as `0x1`
|
||||
* (rather than `0xff..ff`).
|
||||
*
|
||||
* This implies that `~true` in this implementation becomes
|
||||
* `0xff..fe` (rather than `0x0`): for this reason, to be used in
|
||||
* the if expression, we mask out only the last bit in the next
|
||||
* line.
|
||||
*/
|
||||
points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)) & 1;
|
||||
|
||||
if (points_equal) {
|
||||
/*
|
||||
* This is obviously not constant-time but, as mentioned before, this
|
||||
* case never happens during single point multiplication, so there is no
|
||||
* timing leak for ECDH or ECDSA signing.
|
||||
*/
|
||||
point_double(x3, y3, z3, x1, y1, z1);
|
||||
return;
|
||||
}
|
||||
|
@ -1402,8 +1416,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
felem_bytearray *secrets = NULL;
|
||||
felem (*pre_comp)[17][3] = NULL;
|
||||
felem *tmp_felems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned num_bytes;
|
||||
int num_bytes;
|
||||
int have_pre_comp = 0;
|
||||
size_t num_points = num;
|
||||
felem x_in, y_in, z_in, x_out, y_out, z_out;
|
||||
|
@ -1478,14 +1491,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
* i.e., they contribute nothing to the linear combination
|
||||
*/
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
if (i == num) {
|
||||
/* the generator */
|
||||
{
|
||||
p = EC_GROUP_get0_generator(group);
|
||||
p_scalar = scalar;
|
||||
} else
|
||||
} else {
|
||||
/* the i^th point */
|
||||
{
|
||||
p = points[i];
|
||||
p_scalar = scalars[i];
|
||||
}
|
||||
|
@ -1501,10 +1512,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(p_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
}
|
||||
if (num_bytes < 0) {
|
||||
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
|
@ -1547,20 +1564,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(scalar, tmp);
|
||||
flip_endian(g_secret, tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
|
||||
}
|
||||
/* do the multiplication with generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
g_secret,
|
||||
mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
|
||||
} else
|
||||
} else {
|
||||
/* do the multiplication without generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
|
||||
}
|
||||
/* reduce the output to its unique minimal representation */
|
||||
felem_contract(x_in, x_out);
|
||||
felem_contract(y_in, y_out);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -39,7 +39,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
|||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
# include "ec_local.h"
|
||||
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
|
@ -74,8 +74,8 @@ static const felem_bytearray nistp256_curve_params[5] = {
|
|||
{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
|
||||
{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc},
|
||||
{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, /* b */
|
||||
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
|
||||
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
|
||||
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
|
||||
|
@ -146,34 +146,21 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
|
|||
*((u64 *)&out[24]) = in[3];
|
||||
}
|
||||
|
||||
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
|
||||
static void flip_endian(u8 *out, const u8 *in, unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; ++i)
|
||||
out[i] = in[len - 1 - i];
|
||||
}
|
||||
|
||||
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
|
||||
static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
{
|
||||
felem_bytearray b_in;
|
||||
felem_bytearray b_out;
|
||||
unsigned num_bytes;
|
||||
int num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof(b_out));
|
||||
num_bytes = BN_num_bytes(bn);
|
||||
if (num_bytes > sizeof(b_out)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
if (BN_is_negative(bn)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
num_bytes = BN_bn2bin(bn, b_in);
|
||||
flip_endian(b_out, b_in, num_bytes);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
bin32_to_felem(out, b_out);
|
||||
return 1;
|
||||
}
|
||||
|
@ -181,10 +168,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
|||
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
|
||||
static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
|
||||
{
|
||||
felem_bytearray b_in, b_out;
|
||||
smallfelem_to_bin32(b_in, in);
|
||||
flip_endian(b_out, b_in, sizeof(b_out));
|
||||
return BN_bin2bn(b_out, sizeof(b_out), out);
|
||||
felem_bytearray b_out;
|
||||
smallfelem_to_bin32(b_out, in);
|
||||
return BN_lebin2bn(b_out, sizeof(b_out), out);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -1255,6 +1241,7 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
longfelem tmp, tmp2;
|
||||
smallfelem small1, small2, small3, small4, small5;
|
||||
limb x_equal, y_equal, z1_is_zero, z2_is_zero;
|
||||
limb points_equal;
|
||||
|
||||
felem_shrink(small3, z1);
|
||||
|
||||
|
@ -1354,7 +1341,26 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
felem_shrink(small1, ftmp5);
|
||||
y_equal = smallfelem_is_zero(small1);
|
||||
|
||||
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
|
||||
/*
|
||||
* The formulae are incorrect if the points are equal, in affine coordinates
|
||||
* (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
|
||||
* happens.
|
||||
*
|
||||
* We use bitwise operations to avoid potential side-channels introduced by
|
||||
* the short-circuiting behaviour of boolean operators.
|
||||
*
|
||||
* The special case of either point being the point at infinity (z1 and/or
|
||||
* z2 are zero), is handled separately later on in this function, so we
|
||||
* avoid jumping to point_double here in those special cases.
|
||||
*/
|
||||
points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero));
|
||||
|
||||
if (points_equal) {
|
||||
/*
|
||||
* This is obviously not constant-time but, as mentioned before, this
|
||||
* case never happens during single point multiplication, so there is no
|
||||
* timing leak for ECDH or ECDSA signing.
|
||||
*/
|
||||
point_double(x3, y3, z3, x1, y1, z1);
|
||||
return;
|
||||
}
|
||||
|
@ -2024,8 +2030,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
felem_bytearray *secrets = NULL;
|
||||
smallfelem (*pre_comp)[17][3] = NULL;
|
||||
smallfelem *tmp_smallfelems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned i, num_bytes;
|
||||
unsigned i;
|
||||
int num_bytes;
|
||||
int have_pre_comp = 0;
|
||||
size_t num_points = num;
|
||||
smallfelem x_in, y_in, z_in;
|
||||
|
@ -2102,17 +2108,15 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
memset(secrets, 0, sizeof(*secrets) * num_points);
|
||||
memset(pre_comp, 0, sizeof(*pre_comp) * num_points);
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
if (i == num) {
|
||||
/*
|
||||
* we didn't have a valid precomputation, so we pick the
|
||||
* generator
|
||||
*/
|
||||
{
|
||||
p = EC_GROUP_get0_generator(group);
|
||||
p_scalar = scalar;
|
||||
} else
|
||||
} else {
|
||||
/* the i^th point */
|
||||
{
|
||||
p = points[i];
|
||||
p_scalar = scalars[i];
|
||||
}
|
||||
|
@ -2128,10 +2132,16 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(p_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
}
|
||||
if (num_bytes < 0) {
|
||||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
|
@ -2176,20 +2186,21 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(scalar, tmp);
|
||||
flip_endian(g_secret, tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
|
||||
}
|
||||
/* do the multiplication with generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
g_secret,
|
||||
mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
|
||||
} else
|
||||
} else {
|
||||
/* do the multiplication without generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
|
||||
}
|
||||
/* reduce the output to its unique minimal representation */
|
||||
felem_contract(x_in, x_out);
|
||||
felem_contract(y_in, y_out);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -38,7 +38,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
|||
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
# include "ec_local.h"
|
||||
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
|
@ -128,6 +128,7 @@ static const felem_bytearray nistp521_curve_params[5] = {
|
|||
# define NLIMBS 9
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef limb limb_aX __attribute((__aligned__(1)));
|
||||
typedef limb felem[NLIMBS];
|
||||
typedef uint128_t largefelem[NLIMBS];
|
||||
|
||||
|
@ -141,14 +142,14 @@ static const limb bottom58bits = 0x3ffffffffffffff;
|
|||
static void bin66_to_felem(felem out, const u8 in[66])
|
||||
{
|
||||
out[0] = (*((limb *) & in[0])) & bottom58bits;
|
||||
out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb *) & in[58])) & bottom57bits;
|
||||
out[1] = (*((limb_aX *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb_aX *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb_aX *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb_aX *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb_aX *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb_aX *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb_aX *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb_aX *) & in[58])) & bottom57bits;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -159,44 +160,31 @@ static void felem_to_bin66(u8 out[66], const felem in)
|
|||
{
|
||||
memset(out, 0, 66);
|
||||
(*((limb *) & out[0])) = in[0];
|
||||
(*((limb *) & out[7])) |= in[1] << 2;
|
||||
(*((limb *) & out[14])) |= in[2] << 4;
|
||||
(*((limb *) & out[21])) |= in[3] << 6;
|
||||
(*((limb *) & out[29])) = in[4];
|
||||
(*((limb *) & out[36])) |= in[5] << 2;
|
||||
(*((limb *) & out[43])) |= in[6] << 4;
|
||||
(*((limb *) & out[50])) |= in[7] << 6;
|
||||
(*((limb *) & out[58])) = in[8];
|
||||
}
|
||||
|
||||
/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
|
||||
static void flip_endian(u8 *out, const u8 *in, unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; ++i)
|
||||
out[i] = in[len - 1 - i];
|
||||
(*((limb_aX *) & out[7])) |= in[1] << 2;
|
||||
(*((limb_aX *) & out[14])) |= in[2] << 4;
|
||||
(*((limb_aX *) & out[21])) |= in[3] << 6;
|
||||
(*((limb_aX *) & out[29])) = in[4];
|
||||
(*((limb_aX *) & out[36])) |= in[5] << 2;
|
||||
(*((limb_aX *) & out[43])) |= in[6] << 4;
|
||||
(*((limb_aX *) & out[50])) |= in[7] << 6;
|
||||
(*((limb_aX *) & out[58])) = in[8];
|
||||
}
|
||||
|
||||
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
|
||||
static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
{
|
||||
felem_bytearray b_in;
|
||||
felem_bytearray b_out;
|
||||
unsigned num_bytes;
|
||||
int num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof(b_out));
|
||||
num_bytes = BN_num_bytes(bn);
|
||||
if (num_bytes > sizeof(b_out)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
if (BN_is_negative(bn)) {
|
||||
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
|
||||
return 0;
|
||||
}
|
||||
num_bytes = BN_bn2bin(bn, b_in);
|
||||
flip_endian(b_out, b_in, num_bytes);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
bin66_to_felem(out, b_out);
|
||||
return 1;
|
||||
}
|
||||
|
@ -204,10 +192,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
|||
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
|
||||
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
|
||||
{
|
||||
felem_bytearray b_in, b_out;
|
||||
felem_to_bin66(b_in, in);
|
||||
flip_endian(b_out, b_in, sizeof(b_out));
|
||||
return BN_bin2bn(b_out, sizeof(b_out), out);
|
||||
felem_bytearray b_out;
|
||||
felem_to_bin66(b_out, in);
|
||||
return BN_lebin2bn(b_out, sizeof(b_out), out);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -357,10 +344,15 @@ static void felem_diff64(felem out, const felem in)
|
|||
static void felem_diff_128_64(largefelem out, const felem in)
|
||||
{
|
||||
/*
|
||||
* In order to prevent underflow, we add 0 mod p before subtracting.
|
||||
* In order to prevent underflow, we add 64p mod p (which is equivalent
|
||||
* to 0 mod p) before subtracting. p is 2^521 - 1, i.e. in binary a 521
|
||||
* digit number with all bits set to 1. See "The representation of field
|
||||
* elements" comment above for a description of how limbs are used to
|
||||
* represent a number. 64p is represented with 8 limbs containing a number
|
||||
* with 58 bits set and one limb with a number with 57 bits set.
|
||||
*/
|
||||
static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
|
||||
static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
|
||||
static const limb two63m6 = (((limb) 1) << 63) - (((limb) 1) << 6);
|
||||
static const limb two63m5 = (((limb) 1) << 63) - (((limb) 1) << 5);
|
||||
|
||||
out[0] += two63m6 - in[0];
|
||||
out[1] += two63m5 - in[1];
|
||||
|
@ -1167,6 +1159,7 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
|
||||
largefelem tmp, tmp2;
|
||||
limb x_equal, y_equal, z1_is_zero, z2_is_zero;
|
||||
limb points_equal;
|
||||
|
||||
z1_is_zero = felem_is_zero(z1);
|
||||
z2_is_zero = felem_is_zero(z2);
|
||||
|
@ -1251,7 +1244,24 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
felem_scalar64(ftmp5, 2);
|
||||
/* ftmp5[i] < 2^61 */
|
||||
|
||||
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
|
||||
/*
|
||||
* The formulae are incorrect if the points are equal, in affine coordinates
|
||||
* (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
|
||||
* happens.
|
||||
*
|
||||
* We use bitwise operations to avoid potential side-channels introduced by
|
||||
* the short-circuiting behaviour of boolean operators.
|
||||
*
|
||||
* The special case of either point being the point at infinity (z1 and/or
|
||||
* z2 are zero), is handled separately later on in this function, so we
|
||||
* avoid jumping to point_double here in those special cases.
|
||||
*
|
||||
* Notice the comment below on the implications of this branching for timing
|
||||
* leaks and why it is considered practically irrelevant.
|
||||
*/
|
||||
points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero));
|
||||
|
||||
if (points_equal) {
|
||||
/*
|
||||
* 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
|
||||
|
@ -1264,7 +1274,7 @@ static void point_add(felem x3, felem y3, felem z3,
|
|||
* ffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb
|
||||
* 71e913863f7, in that case the penultimate intermediate is -9G and
|
||||
* the final digit is also -9G. Since this only happens for a single
|
||||
* scalar, the timing leak is irrelevent. (Any attacker who wanted to
|
||||
* scalar, the timing leak is irrelevant. (Any attacker who wanted to
|
||||
* check whether a secret scalar was that exact value, can already do
|
||||
* so.)
|
||||
*/
|
||||
|
@ -1861,8 +1871,8 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
felem_bytearray *secrets = NULL;
|
||||
felem (*pre_comp)[17][3] = NULL;
|
||||
felem *tmp_felems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned i, num_bytes;
|
||||
unsigned i;
|
||||
int num_bytes;
|
||||
int have_pre_comp = 0;
|
||||
size_t num_points = num;
|
||||
felem x_in, y_in, z_in, x_out, y_out, z_out;
|
||||
|
@ -1937,17 +1947,15 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
* i.e., they contribute nothing to the linear combination
|
||||
*/
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
if (i == num) {
|
||||
/*
|
||||
* we didn't have a valid precomputation, so we pick the
|
||||
* generator
|
||||
*/
|
||||
{
|
||||
p = EC_GROUP_get0_generator(group);
|
||||
p_scalar = scalar;
|
||||
} else
|
||||
} else {
|
||||
/* the i^th point */
|
||||
{
|
||||
p = points[i];
|
||||
p_scalar = scalars[i];
|
||||
}
|
||||
|
@ -1963,10 +1971,16 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(p_scalar,
|
||||
secrets[i], sizeof(secrets[i]));
|
||||
}
|
||||
if (num_bytes < 0) {
|
||||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
|
@ -2009,21 +2023,22 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else
|
||||
num_bytes = BN_bn2bin(scalar, tmp);
|
||||
flip_endian(g_secret, tmp, num_bytes);
|
||||
num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
|
||||
} else {
|
||||
num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
|
||||
}
|
||||
/* do the multiplication with generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
g_secret,
|
||||
mixed, (const felem(*)[17][3])pre_comp,
|
||||
(const felem(*)[3])g_pre_comp);
|
||||
} else
|
||||
} else {
|
||||
/* do the multiplication without generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out,
|
||||
(const felem_bytearray(*))secrets, num_points,
|
||||
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
|
||||
}
|
||||
/* reduce the output to its unique minimal representation */
|
||||
felem_contract(x_in, x_out);
|
||||
felem_contract(y_in, y_out);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -33,7 +33,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
|||
*/
|
||||
|
||||
# include <stddef.h>
|
||||
# include "ec_lcl.h"
|
||||
# include "ec_local.h"
|
||||
|
||||
/*
|
||||
* Convert an array of points into affine coordinates. (If the point at
|
||||
|
@ -158,13 +158,13 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
|||
* of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
|
||||
* by using bit-wise subtraction as follows:
|
||||
*
|
||||
* b_k b_(k-1) ... b_2 b_1 b_0
|
||||
* - b_k ... b_3 b_2 b_1 b_0
|
||||
* -------------------------------------
|
||||
* s_k b_(k-1) ... s_3 s_2 s_1 s_0
|
||||
* b_k b_(k-1) ... b_2 b_1 b_0
|
||||
* - b_k ... b_3 b_2 b_1 b_0
|
||||
* -----------------------------------------
|
||||
* s_(k+1) s_k ... s_3 s_2 s_1 s_0
|
||||
*
|
||||
* A left-shift followed by subtraction of the original value yields a new
|
||||
* representation of the same value, using signed bits s_i = b_(i+1) - b_i.
|
||||
* representation of the same value, using signed bits s_i = b_(i-1) - b_i.
|
||||
* This representation from Booth's paper has since appeared in the
|
||||
* literature under a variety of different names including "reversed binary
|
||||
* form", "alternating greedy expansion", "mutual opposite form", and
|
||||
|
@ -188,7 +188,7 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
|||
* (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
|
||||
* signed bits into a signed digit:
|
||||
*
|
||||
* s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
|
||||
* s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j)
|
||||
*
|
||||
* The sign-alternating property implies that the resulting digit values are
|
||||
* integers from -16 to 16.
|
||||
|
@ -196,14 +196,14 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
|||
* Of course, we don't actually need to compute the signed digits s_i as an
|
||||
* intermediate step (that's just a nice way to see how this scheme relates
|
||||
* to the wNAF): a direct computation obtains the recoded digit from the
|
||||
* six bits b_(4j + 4) ... b_(4j - 1).
|
||||
* six bits b_(5j + 4) ... b_(5j - 1).
|
||||
*
|
||||
* This function takes those five bits as an integer (0 .. 63), writing the
|
||||
* This function takes those six bits as an integer (0 .. 63), writing the
|
||||
* recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
|
||||
* value, in the range 0 .. 8). Note that this integer essentially provides the
|
||||
* input bits "shifted to the left" by one position: for example, the input to
|
||||
* compute the least significant recoded digit, given that there's no bit b_-1,
|
||||
* has to be b_4 b_3 b_2 b_1 b_0 0.
|
||||
* value, in the range 0 .. 16). Note that this integer essentially provides
|
||||
* the input bits "shifted to the left" by one position: for example, the input
|
||||
* to compute the least significant recoded digit, given that there's no bit
|
||||
* 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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2014-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2014, Intel Corporation. All Rights Reserved.
|
||||
* Copyright (c) 2015, CloudFlare, Inc.
|
||||
*
|
||||
|
@ -21,8 +21,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "ec_local.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
#if BN_BITS2 != 64
|
||||
|
@ -358,16 +358,47 @@ static void ecp_nistz256_point_add(P256_POINT *r,
|
|||
ecp_nistz256_sub(H, U2, U1); /* H = U2 - U1 */
|
||||
|
||||
/*
|
||||
* This should not happen during sign/ecdh, so no constant time violation
|
||||
* The formulae are incorrect if the points are equal so we check for
|
||||
* this and do doubling if this happens.
|
||||
*
|
||||
* Points here are in Jacobian projective coordinates (Xi, Yi, Zi)
|
||||
* that are bound to the affine coordinates (xi, yi) by the following
|
||||
* equations:
|
||||
* - xi = Xi / (Zi)^2
|
||||
* - y1 = Yi / (Zi)^3
|
||||
*
|
||||
* For the sake of optimization, the algorithm operates over
|
||||
* intermediate variables U1, U2 and S1, S2 that are derived from
|
||||
* the projective coordinates:
|
||||
* - U1 = X1 * (Z2)^2 ; U2 = X2 * (Z1)^2
|
||||
* - S1 = Y1 * (Z2)^3 ; S2 = Y2 * (Z1)^3
|
||||
*
|
||||
* It is easy to prove that is_equal(U1, U2) implies that the affine
|
||||
* x-coordinates are equal, or either point is at infinity.
|
||||
* Likewise is_equal(S1, S2) implies that the affine y-coordinates are
|
||||
* equal, or either point is at infinity.
|
||||
*
|
||||
* The special case of either point being the point at infinity (Z1 or Z2
|
||||
* is zero), is handled separately later on in this function, so we avoid
|
||||
* jumping to point_double here in those special cases.
|
||||
*
|
||||
* When both points are inverse of each other, we know that the affine
|
||||
* x-coordinates are equal, and the y-coordinates have different sign.
|
||||
* Therefore since U1 = U2, we know H = 0, and therefore Z3 = H*Z1*Z2
|
||||
* will equal 0, thus the result is infinity, if we simply let this
|
||||
* function continue normally.
|
||||
*
|
||||
* We use bitwise operations to avoid potential side-channels introduced by
|
||||
* the short-circuiting behaviour of boolean operators.
|
||||
*/
|
||||
if (is_equal(U1, U2) && !in1infty && !in2infty) {
|
||||
if (is_equal(S1, S2)) {
|
||||
ecp_nistz256_point_double(r, a);
|
||||
return;
|
||||
} else {
|
||||
memset(r, 0, sizeof(*r));
|
||||
return;
|
||||
}
|
||||
if (is_equal(U1, U2) & ~in1infty & ~in2infty & is_equal(S1, S2)) {
|
||||
/*
|
||||
* This is obviously not constant-time but it should never happen during
|
||||
* single point multiplication, so there is no timing leak for ECDH or
|
||||
* ECDSA signing.
|
||||
*/
|
||||
ecp_nistz256_point_double(r, a);
|
||||
return;
|
||||
}
|
||||
|
||||
ecp_nistz256_sqr_mont(Rsqr, R); /* R^2 */
|
||||
|
@ -888,8 +919,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
|
||||
EC_nistz256_pre_comp_free(pre_comp);
|
||||
|
@ -899,207 +929,6 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great
|
||||
* code processing 4 points in parallel, corresponding serial operation
|
||||
* is several times slower, because it uses 29x29=58-bit multiplication
|
||||
* as opposite to 64x64=128-bit in integer-only scalar case. As result
|
||||
* it doesn't provide *significant* performance improvement. Note that
|
||||
* just defining ECP_NISTZ256_AVX2 is not sufficient to make it work,
|
||||
* you'd need to compile even asm/ecp_nistz256-avx.pl module.
|
||||
*/
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
# if !(defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64)) || \
|
||||
!(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */
|
||||
# undef ECP_NISTZ256_AVX2
|
||||
# else
|
||||
/* Constant time access, loading four values, from four consecutive tables */
|
||||
void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in,
|
||||
int index0, int index1, int index2,
|
||||
int index3);
|
||||
void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in);
|
||||
void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4);
|
||||
void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_set1(void *RESULTx4);
|
||||
int ecp_nistz_avx2_eligible(void);
|
||||
|
||||
static void booth_recode_w7(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in)
|
||||
{
|
||||
unsigned char s, d;
|
||||
|
||||
s = ~((in >> 7) - 1);
|
||||
d = (1 << 8) - in - 1;
|
||||
d = (d & s) | (in & ~s);
|
||||
d = (d >> 1) + (d & 1);
|
||||
|
||||
*sign = s & 1;
|
||||
*digit = d;
|
||||
}
|
||||
|
||||
/*
|
||||
* ecp_nistz256_avx2_mul_g performs multiplication by G, using only the
|
||||
* precomputed table. It does 4 affine point additions in parallel,
|
||||
* significantly speeding up point multiplication for a fixed value.
|
||||
*/
|
||||
static void ecp_nistz256_avx2_mul_g(P256_POINT *r,
|
||||
unsigned char p_str[33],
|
||||
const P256_POINT_AFFINE(*preComputedTable)[64])
|
||||
{
|
||||
const unsigned int window_size = 7;
|
||||
const unsigned int mask = (1 << (window_size + 1)) - 1;
|
||||
unsigned int wvalue;
|
||||
/* Using 4 windows at a time */
|
||||
unsigned char sign0, digit0;
|
||||
unsigned char sign1, digit1;
|
||||
unsigned char sign2, digit2;
|
||||
unsigned char sign3, digit3;
|
||||
unsigned int idx = 0;
|
||||
BN_ULONG tmp[P256_LIMBS];
|
||||
int i;
|
||||
|
||||
ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 };
|
||||
ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 };
|
||||
ALIGN32 P256_POINT_AFFINE point_arr[4];
|
||||
ALIGN32 P256_POINT res_point_arr[4];
|
||||
|
||||
/* Initial four windows */
|
||||
wvalue = *((u16 *) & p_str[0]);
|
||||
wvalue = (wvalue << 1) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(aX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(aX4, aX4);
|
||||
ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]);
|
||||
ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]);
|
||||
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
/* Optimized when both inputs are affine */
|
||||
ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4);
|
||||
|
||||
for (i = 2; i < 9; i++) {
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr,
|
||||
preComputedTable[4 * i],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
|
||||
ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4);
|
||||
}
|
||||
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]);
|
||||
|
||||
ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4);
|
||||
/* Last window is performed serially */
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r,
|
||||
preComputedTable[36], digit0);
|
||||
ecp_nistz256_neg(tmp, r->Y);
|
||||
copy_conditional(r->Y, tmp, sign0);
|
||||
memcpy(r->Z, ONE, sizeof(ONE));
|
||||
/* Sum the four windows */
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[0]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[1]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[2]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[3]);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
__owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group,
|
||||
const P256_POINT_AFFINE *in,
|
||||
BN_CTX *ctx)
|
||||
|
@ -1189,6 +1018,8 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
|||
}
|
||||
|
||||
if (preComputedTable) {
|
||||
BN_ULONG infty;
|
||||
|
||||
if ((BN_num_bits(scalar) > 256)
|
||||
|| BN_is_negative(scalar)) {
|
||||
if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)
|
||||
|
@ -1220,67 +1051,58 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
|||
for (; i < 33; i++)
|
||||
p_str[i] = 0;
|
||||
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
if (ecp_nistz_avx2_eligible()) {
|
||||
ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
BN_ULONG infty;
|
||||
/* First window */
|
||||
wvalue = (p_str[0] << 1) & mask;
|
||||
idx += window_size;
|
||||
|
||||
/* First window */
|
||||
wvalue = (p_str[0] << 1) & mask;
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
|
||||
wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
|
||||
/*
|
||||
* Since affine infinity is encoded as (0,0) and
|
||||
* Jacobian is (,,0), we need to harmonize them
|
||||
* by assigning "one" or zero to Z.
|
||||
*/
|
||||
infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
|
||||
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
|
||||
if (P256_LIMBS == 8)
|
||||
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
|
||||
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
|
||||
|
||||
infty = 0 - is_zero(infty);
|
||||
infty = ~infty;
|
||||
|
||||
p.p.Z[0] = ONE[0] & infty;
|
||||
p.p.Z[1] = ONE[1] & infty;
|
||||
p.p.Z[2] = ONE[2] & infty;
|
||||
p.p.Z[3] = ONE[3] & infty;
|
||||
if (P256_LIMBS == 8) {
|
||||
p.p.Z[4] = ONE[4] & infty;
|
||||
p.p.Z[5] = ONE[5] & infty;
|
||||
p.p.Z[6] = ONE[6] & infty;
|
||||
p.p.Z[7] = ONE[7] & infty;
|
||||
}
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned int off = (idx - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
|
||||
wvalue >> 1);
|
||||
ecp_nistz256_gather_w7(&t.a,
|
||||
preComputedTable[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
/*
|
||||
* Since affine infinity is encoded as (0,0) and
|
||||
* Jacobian ias (,,0), we need to harmonize them
|
||||
* by assigning "one" or zero to Z.
|
||||
*/
|
||||
infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
|
||||
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
|
||||
if (P256_LIMBS == 8)
|
||||
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
|
||||
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
|
||||
|
||||
infty = 0 - is_zero(infty);
|
||||
infty = ~infty;
|
||||
|
||||
p.p.Z[0] = ONE[0] & infty;
|
||||
p.p.Z[1] = ONE[1] & infty;
|
||||
p.p.Z[2] = ONE[2] & infty;
|
||||
p.p.Z[3] = ONE[3] & infty;
|
||||
if (P256_LIMBS == 8) {
|
||||
p.p.Z[4] = ONE[4] & infty;
|
||||
p.p.Z[5] = ONE[5] & infty;
|
||||
p.p.Z[6] = ONE[6] & infty;
|
||||
p.p.Z[7] = ONE[7] & infty;
|
||||
}
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned int off = (idx - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&t.a,
|
||||
preComputedTable[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
} else {
|
||||
p_is_infinity = 1;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/symhacks.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
EC_POINT *point,
|
||||
|
|
317
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_smpl.c
vendored
317
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_smpl.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 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
|
||||
|
@ -11,7 +11,7 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/symhacks.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_simple_method(void)
|
||||
{
|
||||
|
@ -307,8 +307,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
|
|||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
@ -787,8 +786,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
|||
ret = 1;
|
||||
|
||||
end:
|
||||
if (ctx) /* otherwise we already called BN_CTX_end */
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1374,6 +1372,7 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
|||
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||
* 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)
|
||||
|
@ -1433,112 +1432,133 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
|||
temp = BN_CTX_get(ctx);
|
||||
if (temp == NULL) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* make sure lambda is not zero */
|
||||
/*-
|
||||
* Make sure lambda is not zero.
|
||||
* If the RNG fails, we cannot blind but nevertheless want
|
||||
* code to continue smoothly and not clobber the error stack.
|
||||
*/
|
||||
do {
|
||||
if (!BN_priv_rand_range(lambda, group->field)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
ERR_set_mark();
|
||||
ret = BN_priv_rand_range(lambda, group->field);
|
||||
ERR_pop_to_mark();
|
||||
if (ret == 0) {
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
} while (BN_is_zero(lambda));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->X, p->X, temp, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, temp, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto err;
|
||||
p->Z_is_one = 0;
|
||||
if ((group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)
|
||||
|| !group->meth->field_sqr(group, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->X, p->X, temp, ctx)
|
||||
|| !group->meth->field_mul(group, temp, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto end;
|
||||
|
||||
p->Z_is_one = 0;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
end:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Set s := p, r := 2p.
|
||||
* Input:
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := p, r := 2p: blinded projective (homogeneous) coordinates
|
||||
*
|
||||
* For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve
|
||||
* multiplication resistant against side channel attacks" appendix, as described
|
||||
* at
|
||||
* multiplication resistant against side channel attacks" appendix, described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2
|
||||
* simplified for Z1=1.
|
||||
*
|
||||
* The input point p will be in randomized Jacobian projective coords:
|
||||
* x = X/Z**2, y=Y/Z**3
|
||||
*
|
||||
* The output points p, s, and r are converted to standard (homogeneous)
|
||||
* projective coords:
|
||||
* x = X/Z, y=Y/Z
|
||||
* 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)
|
||||
{
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
|
||||
|
||||
t1 = r->Z;
|
||||
t2 = r->Y;
|
||||
t1 = s->Z;
|
||||
t2 = r->Z;
|
||||
t3 = s->X;
|
||||
t4 = r->X;
|
||||
t5 = s->Y;
|
||||
t6 = s->Z;
|
||||
|
||||
/* convert p: (X,Y,Z) -> (XZ,Y,Z**3) */
|
||||
if (!group->meth->field_mul(group, p->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, t1, ctx)
|
||||
/* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t2, p->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t3, group->a, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t2, t4, group->field)
|
||||
|| !BN_mod_add_quick(t2, t2, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t3, group->b, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t1, t6, ctx)
|
||||
|| !BN_mod_lshift_quick(t4, t4, 3, group->field)
|
||||
if (!p->Z_is_one /* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t3, p->X, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t3, group->a, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t5, p->X, group->b, ctx)
|
||||
|| !BN_mod_lshift_quick(t5, t5, 3, group->field)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t3, t6, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t2, group->field)
|
||||
|| !BN_mod_sub_quick(r->X, t4, t5, group->field)
|
||||
|| !BN_mod_add_quick(t1, t3, group->a, group->field)
|
||||
|| !group->meth->field_mul(group, t2, p->X, t1, ctx)
|
||||
|| !BN_mod_add_quick(t2, group->b, t2, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_lshift_quick(r->Z, t1, 2, group->field)
|
||||
|| !EC_POINT_copy(s, p))
|
||||
|| !BN_mod_lshift_quick(r->Z, t2, 2, group->field))
|
||||
return 0;
|
||||
|
||||
/* make sure lambda (r->Y here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand_range(r->Y, group->field))
|
||||
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))
|
||||
return 0;
|
||||
} while (BN_is_zero(s->Z));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& (!group->meth->field_encode(group, r->Y, r->Y, ctx)
|
||||
|| !group->meth->field_encode(group, s->Z, s->Z, ctx)))
|
||||
return 0;
|
||||
|
||||
/* blind r and s independently */
|
||||
if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, r->X, r->X, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */
|
||||
return 0;
|
||||
|
||||
r->Z_is_one = 0;
|
||||
s->Z_is_one = 0;
|
||||
p->Z_is_one = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := r + s, r := 2r: projective (homogeneous) coordinates
|
||||
*
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* "A fast parallel elliptic curve multiplication resistant against side channel
|
||||
* attacks", as described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-4
|
||||
* 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 ret = 0;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7 = NULL;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
t0 = BN_CTX_get(ctx);
|
||||
|
@ -1548,50 +1568,47 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
|||
t4 = BN_CTX_get(ctx);
|
||||
t5 = BN_CTX_get(ctx);
|
||||
t6 = BN_CTX_get(ctx);
|
||||
t7 = BN_CTX_get(ctx);
|
||||
|
||||
if (t7 == NULL
|
||||
|| !group->meth->field_mul(group, t0, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t1, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->X, s->Z, ctx)
|
||||
if (t6 == NULL
|
||||
|| !group->meth->field_mul(group, t6, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, r->X, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t3, r->Z, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t4, group->a, t1, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t4, group->field)
|
||||
|| !BN_mod_add_quick(t4, t3, t2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t4, t0, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_lshift_quick(t7, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t7, t1, ctx)
|
||||
|| !BN_mod_lshift1_quick(t0, t0, group->field)
|
||||
|| !BN_mod_add_quick(t0, t1, t0, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t2, t3, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t1, p->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->Z, t0, ctx)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_mul(group, s->Z, p->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t2, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t2, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t5, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t5, t3, group->field)
|
||||
|| !BN_mod_sub_quick(t5, t5, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t7, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t5, group->a, t0, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !BN_mod_add_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t7, t3, t7, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t5, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t6, t5, ctx)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !BN_mod_lshift_quick(t2, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_sqr(group, s->Z, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t4, s->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t5, group->field)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t5, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t1, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_sub_quick(t1, t1, t4, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t1, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t3, t0, group->field)
|
||||
|| !BN_mod_add_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t4, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t1, t3, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, t1, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_add_quick(r->Z, t7, t5, group->field))
|
||||
|| !BN_mod_add_quick(r->Z, t4, t1, group->field))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
@ -1602,17 +1619,23 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
|||
}
|
||||
|
||||
/*-
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in projective
|
||||
* coordinates and return r in Jacobian projective coordinates.
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2*Z1;
|
||||
* Y4 = two*b*Z3*SQR(Z2*Z1) + Z3*(a*Z2*Z1+X1*X2)*(X1*Z2+X2*Z1) - X3*SQR(X1*Z2-X2*Z1);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2)*Z1;
|
||||
* Output:
|
||||
* - r := (x,y): affine coordinates
|
||||
*
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in mixed
|
||||
* projective coords, i.e. p is affine and (r,s) in projective (homogeneous)
|
||||
* coords, and return r in affine coordinates.
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2;
|
||||
* Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2);
|
||||
*
|
||||
* Z4 != 0 because:
|
||||
* - Z1==0 implies p is at infinity, which would have caused an early exit in
|
||||
* the caller;
|
||||
* - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch);
|
||||
* - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch);
|
||||
* - Y1==0 implies p has order 2, so either r or s are infinity and handled by
|
||||
|
@ -1629,11 +1652,7 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
|||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
if (BN_is_zero(s->Z)) {
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
if (!group->meth->field_mul(group, r->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, p->Y, r->Z, ctx)
|
||||
|| !BN_copy(r->Z, p->Z)
|
||||
if (!EC_POINT_copy(r, p)
|
||||
|| !EC_POINT_invert(group, r, ctx))
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -1649,38 +1668,46 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
|||
t6 = BN_CTX_get(ctx);
|
||||
|
||||
if (t6 == NULL
|
||||
|| !BN_mod_lshift1_quick(t0, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t1, r->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t2, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t4, t2, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t2, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->X, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t2, t6, t1, group->field)
|
||||
|| !group->meth->field_mul(group, t5, t5, t2, ctx)
|
||||
|| !BN_mod_sub_quick(t6, t6, t1, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t6, s->X, ctx)
|
||||
|| !BN_mod_add_quick(t4, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, s->Z, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, p->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, r->Z, t0, ctx)
|
||||
/* t3 := X, t4 := Y */
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
|| !group->meth->field_mul(group, r->X, t3, r->Z, ctx)
|
||||
|| !BN_mod_lshift1_quick(t4, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->X, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t6, s->Z, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->Z, t6, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t4, t3, ctx))
|
||||
|| !group->meth->field_mul(group, t2, t3, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, r->X, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t6, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->X, r->Z, ctx)
|
||||
|| !BN_mod_add_quick(t6, r->X, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t6, t6, t1, ctx)
|
||||
|| !BN_mod_add_quick(t6, t6, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t0, t0, r->X, group->field)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t0, s->X, ctx)
|
||||
|| !BN_mod_sub_quick(t0, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t3, t1, ctx)
|
||||
|| (group->meth->field_decode != NULL
|
||||
&& !group->meth->field_decode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_inv(group, t1, t1, ctx)
|
||||
|| (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_mul(group, r->X, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t0, t1, ctx))
|
||||
goto err;
|
||||
|
||||
if (group->meth->field_set_to_one != NULL) {
|
||||
if (!group->meth->field_set_to_one(group, r->Z, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_one(r->Z))
|
||||
goto err;
|
||||
}
|
||||
|
||||
r->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "curve448/curve448_lcl.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "ec_local.h"
|
||||
#include "curve448/curve448_local.h"
|
||||
|
||||
#define X25519_BITS 253
|
||||
#define X25519_SECURITY_BITS 128
|
||||
|
@ -191,7 +191,7 @@ static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
|||
}
|
||||
|
||||
rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
ASN1_STRING_clear_free(oct);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
|||
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
|
||||
if (alg2)
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
|
||||
/* Algorithm idetifiers set: carry on as normal */
|
||||
/* Algorithm identifiers set: carry on as normal */
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue