From 4099618de2cce5099ac2ec5ce8f2d80f4585606e Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 24 Sep 2014 22:46:56 -0700 Subject: [PATCH] ed25519_open(): check that S < l Not strictly required, but I don't see any downsides either. --- .../crypto_sign/ed25519/ref10/open.c | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libsodium/crypto_sign/ed25519/ref10/open.c b/src/libsodium/crypto_sign/ed25519/ref10/open.c index 488333e9..fcc058f5 100644 --- a/src/libsodium/crypto_sign/ed25519/ref10/open.c +++ b/src/libsodium/crypto_sign/ed25519/ref10/open.c @@ -9,6 +9,27 @@ #include "sc.h" #include "utils.h" +static int +crypto_sign_check_S_lt_l(const unsigned char *S) +{ + static const unsigned char l[32] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; + unsigned char c = 0; + unsigned char n = 1; + unsigned int i = 32; + + do { + i--; + c |= ((S[i] - l[i]) >> 8) & n; + n &= ((S[i] ^ l[i]) - 1) >> 8; + } while (i != 0); + + return -(c == 0); +} + int crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) @@ -21,7 +42,7 @@ crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, ge_p3 A; ge_p2 R; - if (sig[63] & 224) { + if (crypto_sign_check_S_lt_l(sig + 32) != 0) { return -1; } if (ge_frombytes_negate_vartime(&A, pk) != 0) {