From b9dd94b9b2a409459d6231cb6f196dfeefc85c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 16 May 2018 00:27:43 +0200 Subject: [PATCH] bn: Use int instead of u32 for sizes The loops relied on unsigned integer overflow, which is not immediately obvious. Replace them with less clever variants that are clearer. Also implement bn_compare using std::memcmp. --- Source/Core/Common/Crypto/bn.cpp | 75 ++++++++++++-------------------- Source/Core/Common/Crypto/bn.h | 12 ++--- 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/Source/Core/Common/Crypto/bn.cpp b/Source/Core/Common/Crypto/bn.cpp index 78ea444384..339b269d39 100644 --- a/Source/Core/Common/Crypto/bn.cpp +++ b/Source/Core/Common/Crypto/bn.cpp @@ -3,61 +3,43 @@ // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt #include -#include +#include #include "Common/CommonTypes.h" #include "Common/Crypto/bn.h" -static void bn_zero(u8* d, u32 n) +static void bn_zero(u8* d, int n) { - memset(d, 0, n); + std::memset(d, 0, n); } -static void bn_copy(u8* d, const u8* a, u32 n) +static void bn_copy(u8* d, const u8* a, int n) { - memcpy(d, a, n); + std::memcpy(d, a, n); } -int bn_compare(const u8* a, const u8* b, u32 n) +int bn_compare(const u8* a, const u8* b, int n) { - u32 i; + return std::memcmp(a, b, n); +} - for (i = 0; i < n; i++) +void bn_sub_modulus(u8* a, const u8* N, int n) +{ + u8 c = 0; + for (int i = n - 1; i >= 0; --i) { - if (a[i] < b[i]) - return -1; - if (a[i] > b[i]) - return 1; - } - - return 0; -} - -void bn_sub_modulus(u8* a, const u8* N, u32 n) -{ - u32 i; - u32 dig; - u8 c; - - c = 0; - for (i = n - 1; i < n; i--) - { - dig = N[i] + c; + u32 dig = N[i] + c; c = (a[i] < dig); a[i] -= dig; } } -void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n) +void bn_add(u8* d, const u8* a, const u8* b, const u8* N, int n) { - u32 i; - u32 dig; - u8 c; - - c = 0; - for (i = n - 1; i < n; i--) + u8 c = 0; + for (int i = n - 1; i >= 0; --i) { - dig = a[i] + b[i] + c; + u32 dig = a[i] + b[i] + c; c = (dig >= 0x100); d[i] = dig; } @@ -69,32 +51,30 @@ void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n) bn_sub_modulus(d, N, n); } -void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, u32 n) +void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, int n) { - u32 i; - u8 mask; - bn_zero(d, n); - for (i = 0; i < n; i++) - for (mask = 0x80; mask != 0; mask >>= 1) + for (int i = 0; i < n; i++) + { + for (u8 mask = 0x80; mask != 0; mask >>= 1) { bn_add(d, d, d, N, n); if ((a[i] & mask) != 0) bn_add(d, d, b, N, n); } + } } -void bn_exp(u8* d, const u8* a, const u8* N, u32 n, const u8* e, u32 en) +void bn_exp(u8* d, const u8* a, const u8* N, int n, const u8* e, int en) { u8 t[512]; - u32 i; - u8 mask; bn_zero(d, n); d[n - 1] = 1; - for (i = 0; i < en; i++) - for (mask = 0x80; mask != 0; mask >>= 1) + for (int i = 0; i < en; i++) + { + for (u8 mask = 0x80; mask != 0; mask >>= 1) { bn_mul(t, d, d, N, n); if ((e[i] & mask) != 0) @@ -102,10 +82,11 @@ void bn_exp(u8* d, const u8* a, const u8* N, u32 n, const u8* e, u32 en) else bn_copy(d, t, n); } + } } // only for prime N -- stupid but lazy, see if I care -void bn_inv(u8* d, const u8* a, const u8* N, u32 n) +void bn_inv(u8* d, const u8* a, const u8* N, int n) { u8 t[512], s[512]; diff --git a/Source/Core/Common/Crypto/bn.h b/Source/Core/Common/Crypto/bn.h index 5c0c85b157..7ab2ab3fb1 100644 --- a/Source/Core/Common/Crypto/bn.h +++ b/Source/Core/Common/Crypto/bn.h @@ -8,9 +8,9 @@ // bignum arithmetic -int bn_compare(const u8* a, const u8* b, u32 n); -void bn_sub_modulus(u8* a, const u8* N, u32 n); -void bn_add(u8* d, const u8* a, const u8* b, const u8* N, u32 n); -void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, u32 n); -void bn_inv(u8* d, const u8* a, const u8* N, u32 n); // only for prime N -void bn_exp(u8* d, const u8* a, const u8* N, u32 n, const u8* e, u32 en); +int bn_compare(const u8* a, const u8* b, int n); +void bn_sub_modulus(u8* a, const u8* N, int n); +void bn_add(u8* d, const u8* a, const u8* b, const u8* N, int n); +void bn_mul(u8* d, const u8* a, const u8* b, const u8* N, int n); +void bn_inv(u8* d, const u8* a, const u8* N, int n); // only for prime N +void bn_exp(u8* d, const u8* a, const u8* N, int n, const u8* e, int en);