From 6489053da9e3ee370e4408bb242aa94512315a9e Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Tue, 10 Oct 2023 05:57:03 +0000 Subject: [PATCH] Fix another even modulus pow uninitialized mem (#280) --- .../arithmetic/bigints_views.nim | 18 +++++----- .../arithmetic/limbs_mod2k.nim | 5 ++- tests/t_ethereum_evm_modexp.nim | 35 ++++++++++++++++++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim b/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim index 8881252..0d2615f 100644 --- a/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim +++ b/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim @@ -170,28 +170,28 @@ func powMod_vartime*( # https://cetinkayakoc.net/docs/j34.pdf let qBits = mBits-ctz - let pBits = 1+ctz + let kBits = 1+ctz let qWords = qBits.wordsRequired() - let pWords = pBits.wordsRequired() + let kWords = kBits.wordsRequired() var qBuf = allocStackArray(SecretWord, qWords) var a1Buf = allocStackArray(SecretWord, qWords) - var a2Buf = allocStackArray(SecretWord, pWords) - var yBuf = allocStackArray(SecretWord, pWords) - var qInv2kBuf = allocStackArray(SecretWord, pWords) + var a2Buf = allocStackArray(SecretWord, kWords) + var yBuf = allocStackArray(SecretWord, kWords) + var qInv2kBuf = allocStackArray(SecretWord, kWords) template q: untyped = qBuf.toOpenArray(0, qWords-1) template a1: untyped = a1Buf.toOpenArray(0, qWords-1) - template a2: untyped = a2Buf.toOpenArray(0, pWords-1) - template y: untyped = yBuf.toOpenArray(0, pWords-1) - template qInv2k: untyped = qInv2kBuf.toOpenArray(0, pWords-1) + template a2: untyped = a2Buf.toOpenArray(0, kWords-1) + template y: untyped = yBuf.toOpenArray(0, kWords-1) + template qInv2k: untyped = qInv2kBuf.toOpenArray(0, kWords-1) q.shiftRight_vartime(M, ctz) a1.powOddMod_vartime(a, exponent, q, window) a2.powMod2k_vartime(a, exponent, k = uint ctz) - qInv2k.invMod2k_vartime(qBuf.toOpenArray(0, qWords-1), uint ctz) + qInv2k.invMod2k_vartime(q, uint ctz) y.submod2k_vartime(a2, a1, uint ctz) y.mulmod2k_vartime(y, qInv2k, uint ctz) diff --git a/constantine/math_arbitrary_precision/arithmetic/limbs_mod2k.nim b/constantine/math_arbitrary_precision/arithmetic/limbs_mod2k.nim index ac33f80..98cf6b6 100644 --- a/constantine/math_arbitrary_precision/arithmetic/limbs_mod2k.nim +++ b/constantine/math_arbitrary_precision/arithmetic/limbs_mod2k.nim @@ -145,9 +145,12 @@ func powMod2k_vartime*( var sBuf = allocStackArray(SecretWord, r.len) template s: untyped = sBuf.toOpenArray(0, r.len-1) - for i in 0 ..< min(r.len, a.len): + let truncLen = min(r.len, a.len) + for i in 0 ..< truncLen: # range [r.len, a.len) will be truncated (mod 2ᵏ) sBuf[i] = a[i] + for i in truncLen ..< r.len: + sBuf[i] = Zero # TODO: sliding/fixed window exponentiation for i in countdown(exponent.len-1, 0): diff --git a/tests/t_ethereum_evm_modexp.nim b/tests/t_ethereum_evm_modexp.nim index c93dc05..3f1442f 100644 --- a/tests/t_ethereum_evm_modexp.nim +++ b/tests/t_ethereum_evm_modexp.nim @@ -73,7 +73,7 @@ suite "EVM ModExp precompile (EIP-198)": doAssert status == cttEVM_Success doAssert r[0] == 0, ". Result was " & $r[0] - test "Audit #5-3 - temp buffer extra unintialized word": + test "Audit #5-3 - temp buffer extra uninitialized word": let input = [ # Length of base (1) @@ -104,6 +104,39 @@ suite "EVM ModExp precompile (EIP-198)": doAssert status == cttEVM_Success doAssert r == @[byte 0, 0, 1, 45, 106, 227, 225, 162, 136], ". Result was " & $r + test "Audit #5-4 - temp buffer extra uninitialized word (2)": + var input = [ + # Length of base + uint8 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + + # Length of exponent + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + + # Length of modulus + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, + + # Base + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + + + # Exponent + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + + # Modulus + 0x17, 0xc6, 0xab, 0xaa, 0x3f, 0x00, 0xe5, 0xc0, 0x5b, 0x75, 0x74, 0xcb, + 0xcf, 0x2a, 0x44, 0xd4, 0x3a, 0xca, 0x4a, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + var r = newSeq[byte](0x2b) + let status = eth_evm_modexp(r, input) + doAssert status == cttEVM_Success + doAssert r == @[byte 10, 141, 74, 46, 2, 18, 2, 37, 247, 220, 246, 65, 109, 246, 7, 144, 85, 202, 194, 191, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], ". Result was " & $r + test "Audit #8 - off-by-1 buffer overflow - ptr + length exclusive vs openArray(lo, hi) inclusive": let input = [ # Length of base (24)