From 18c03de38376da4106191a4de9a2114bb289295a Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 20 Jan 2025 11:30:24 -0800 Subject: [PATCH] arithmetic internals: Further clarify bn_mul_mont ABI. The checks are superceded by the checks in the Rust code, so replace the checks with documenting the preconditions so we don't need to worry about the functions failing anymore. Document some additional caveats discovered. --- crypto/fipsmodule/bn/asm/armv4-mont.pl | 13 ++++--------- crypto/fipsmodule/bn/asm/armv8-mont.pl | 8 ++++---- crypto/fipsmodule/bn/asm/x86-mont.pl | 5 +++-- crypto/fipsmodule/bn/asm/x86_64-mont.pl | 8 ++++---- src/arithmetic/ffi.rs | 11 ++--------- src/arithmetic/montgomery.rs | 3 +++ 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/crypto/fipsmodule/bn/asm/armv4-mont.pl b/crypto/fipsmodule/bn/asm/armv4-mont.pl index 26982ff9b2..e3bddb91f1 100644 --- a/crypto/fipsmodule/bn/asm/armv4-mont.pl +++ b/crypto/fipsmodule/bn/asm/armv4-mont.pl @@ -118,14 +118,9 @@ bn_mul_mont_nohw: ldr ip,[sp,#4] @ load num stmdb sp!,{r0,r2} @ sp points at argument block - cmp ip,#2 + @ No return value in *ring*. Instead, the caller must ensure num >= 2 mov $num,ip @ load num -#ifdef __thumb2__ - ittt lt -#endif - movlt r0,#0 - addlt sp,sp,#2*4 - blt .Labrt + @ No return value in *ring* stmdb sp!,{r4-r12,lr} @ save 10 registers @@ -259,8 +254,7 @@ add sp,sp,#4 @ skip over tp[num+1] ldmia sp!,{r4-r12,lr} @ restore registers add sp,sp,#2*4 @ skip over {r0,r2} - mov r0,#1 -.Labrt: + @ No return value in *ring* #if __ARM_ARCH>=5 ret @ bx lr #else @@ -714,6 +708,7 @@ mov sp,ip vldmia sp!,{d8-d15} ldmia sp!,{r4-r11} + @ No return value in *ring* ret @ bx lr .size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon #endif diff --git a/crypto/fipsmodule/bn/asm/armv8-mont.pl b/crypto/fipsmodule/bn/asm/armv8-mont.pl index efee199029..368039a408 100644 --- a/crypto/fipsmodule/bn/asm/armv8-mont.pl +++ b/crypto/fipsmodule/bn/asm/armv8-mont.pl @@ -55,7 +55,7 @@ $lo1,$hi1,$nj,$m1,$nlo,$nhi, $ovf, $i,$j,$tp,$tj) = map("x$_",6..17,19..24); -# int bn_mul_mont( +# void bn_mul_mont( $rp="x0"; # BN_ULONG *rp, $ap="x1"; # const BN_ULONG *ap, $bp="x2"; # const BN_ULONG *bp, @@ -267,7 +267,7 @@ ldp x19,x20,[x29,#16] mov sp,x29 ldp x21,x22,[x29,#32] - mov x0,#1 + // No return value in *ring*. ldp x23,x24,[x29,#48] ldr x29,[sp],#64 AARCH64_VALIDATE_LINK_REGISTER @@ -1041,7 +1041,7 @@ ldp x19,x20,[x29,#16] mov sp,x29 ldp x21,x22,[x29,#32] - mov x0,#1 + // No return value in *ring*. ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] @@ -1502,7 +1502,7 @@ ldp x19,x20,[x29,#16] mov sp,x29 ldp x21,x22,[x29,#32] - mov x0,#1 + // No return value in *ring*. ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] diff --git a/crypto/fipsmodule/bn/asm/x86-mont.pl b/crypto/fipsmodule/bn/asm/x86-mont.pl index d1eac6c59d..6e30b31d73 100755 --- a/crypto/fipsmodule/bn/asm/x86-mont.pl +++ b/crypto/fipsmodule/bn/asm/x86-mont.pl @@ -65,8 +65,9 @@ $_bpend=&DWP(4*7,"esp"); $frame=32; # size of above frame rounded up to 16n - &xor ("eax","eax"); + # No return value in *ring*. Instead, the caller must ensure num >= 4 &mov ("edi",&wparam(5)); # int num + # No return value in *ring*. &lea ("esi",&wparam(0)); # put aside pointer to argument block &lea ("edx",&wparam(1)); # load ap @@ -325,7 +326,7 @@ &jge (&label("copy")); &mov ("esp",$_sp); # pull saved stack pointer - &mov ("eax",1); + # No return value in *ring*. &function_end("bn_mul_mont"); &asciz("Montgomery Multiplication for x86, CRYPTOGAMS by "); diff --git a/crypto/fipsmodule/bn/asm/x86_64-mont.pl b/crypto/fipsmodule/bn/asm/x86_64-mont.pl index 0034db7fa5..bb996dff38 100755 --- a/crypto/fipsmodule/bn/asm/x86_64-mont.pl +++ b/crypto/fipsmodule/bn/asm/x86_64-mont.pl @@ -310,7 +310,7 @@ mov 8(%rsp,$num,8),%rsi # restore %rsp .cfi_def_cfa %rsi,8 - mov \$1,%rax + # No return value in *ring* mov -48(%rsi),%r15 .cfi_restore %r15 mov -40(%rsi),%r14 @@ -757,7 +757,7 @@ $code.=<<___; mov 8(%rsp,$num,8),%rsi # restore %rsp .cfi_def_cfa %rsi, 8 - mov \$1,%rax + # No return value in *ring* mov -48(%rsi),%r15 .cfi_restore %r15 mov -40(%rsi),%r14 @@ -971,7 +971,7 @@ add \$32,$num jnz .Lsqr8x_cond_copy - mov \$1,%rax + # No return value in *ring* mov -48(%rsi),%r15 .cfi_restore %r15 mov -40(%rsi),%r14 @@ -1340,7 +1340,7 @@ mov %rdx,($tptr) - mov \$1,%rax + # No return value in *ring*. mov -48(%rsi),%r15 .cfi_restore %r15 mov -40(%rsi),%r14 diff --git a/src/arithmetic/ffi.rs b/src/arithmetic/ffi.rs index f6fa09a0a7..a04cdf5d5f 100644 --- a/src/arithmetic/ffi.rs +++ b/src/arithmetic/ffi.rs @@ -12,7 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -use super::{inout::AliasingSlices, n0::N0, LimbSliceError, MAX_LIMBS, MIN_LIMBS}; +use super::{inout::AliasingSlices, n0::N0, LimbSliceError, MAX_LIMBS}; use crate::{c, limb::Limb, polyfill::usize_from_u32}; use core::mem::size_of; @@ -33,7 +33,6 @@ macro_rules! bn_mul_mont_ffi { use crate::{c, limb::Limb}; prefixed_extern! { // `r` and/or 'a' and/or 'b' may alias. - // XXX: BoringSSL declares these functions to return `int`. fn $f( r: *mut Limb, a: *const Limb, @@ -66,14 +65,8 @@ pub(super) unsafe fn bn_mul_mont_ffi Result<(), LimbSliceError> { - assert_eq!(n.len() % LEN_MOD, 0); // The caller should guard against this. - - /// The x86 implementation of `bn_mul_mont`, at least, requires at least 4 - /// limbs. For a long time we have required 4 limbs for all targets, though - /// this may be unnecessary. - const _MIN_LIMBS_AT_LEAST_4: () = assert!(MIN_LIMBS >= 4); // We haven't tested shorter lengths. - assert!(LEN_MIN >= MIN_LIMBS); + assert!(LEN_MIN >= 4); if n.len() < LEN_MIN { return Err(LimbSliceError::too_short(n.len())); } diff --git a/src/arithmetic/montgomery.rs b/src/arithmetic/montgomery.rs index 9c5820e42a..a69f0cd929 100644 --- a/src/arithmetic/montgomery.rs +++ b/src/arithmetic/montgomery.rs @@ -160,6 +160,9 @@ pub(super) fn limbs_mul_mont( }) } } else { + // The x86 implementation of `bn_mul_mont`, at least, requires at least 4 + // limbs. + const _MIN_LIMBS_AT_LEAST_4: () = assert!(MIN_LIMBS >= 4); bn_mul_mont_ffi!(in_out, n, n0, cpu, unsafe { (MIN_LIMBS, MOD_FALLBACK, cpu::Features) => bn_mul_mont })