Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/ecdsa_impl.h
Show All 40 Lines | |||||
* sage: F = FiniteField (p) | * sage: F = FiniteField (p) | ||||
* sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) | * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) | ||||
* '14551231950b75fc4402da1722fc9baee' | * '14551231950b75fc4402da1722fc9baee' | ||||
*/ | */ | ||||
static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( | static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( | ||||
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL | 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL | ||||
); | ); | ||||
static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { | static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const unsigned char *sigend) { | ||||
int lenleft, b1; | size_t lenleft; | ||||
size_t ret = 0; | unsigned char b1; | ||||
VERIFY_CHECK(len != NULL); | |||||
*len = 0; | |||||
if (*sigp >= sigend) { | if (*sigp >= sigend) { | ||||
return -1; | return 0; | ||||
} | } | ||||
b1 = *((*sigp)++); | b1 = *((*sigp)++); | ||||
if (b1 == 0xFF) { | if (b1 == 0xFF) { | ||||
/* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ | /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ | ||||
return -1; | return 0; | ||||
} | } | ||||
if ((b1 & 0x80) == 0) { | if ((b1 & 0x80) == 0) { | ||||
/* X.690-0207 8.1.3.4 short form length octets */ | /* X.690-0207 8.1.3.4 short form length octets */ | ||||
return b1; | *len = b1; | ||||
return 1; | |||||
} | } | ||||
if (b1 == 0x80) { | if (b1 == 0x80) { | ||||
/* Indefinite length is not allowed in DER. */ | /* Indefinite length is not allowed in DER. */ | ||||
return -1; | return 0; | ||||
} | } | ||||
/* X.690-207 8.1.3.5 long form length octets */ | /* X.690-207 8.1.3.5 long form length octets */ | ||||
lenleft = b1 & 0x7F; | lenleft = b1 & 0x7F; /* lenleft is at least 1 */ | ||||
if (lenleft > sigend - *sigp) { | if (lenleft > (size_t)(sigend - *sigp)) { | ||||
return -1; | return 0; | ||||
} | } | ||||
if (**sigp == 0) { | if (**sigp == 0) { | ||||
/* Not the shortest possible length encoding. */ | /* Not the shortest possible length encoding. */ | ||||
return -1; | return 0; | ||||
} | } | ||||
if ((size_t)lenleft > sizeof(size_t)) { | if (lenleft > sizeof(size_t)) { | ||||
/* The resulting length would exceed the range of a size_t, so | /* The resulting length would exceed the range of a size_t, so | ||||
* certainly longer than the passed array size. | * certainly longer than the passed array size. | ||||
*/ | */ | ||||
return -1; | return 0; | ||||
} | } | ||||
while (lenleft > 0) { | while (lenleft > 0) { | ||||
ret = (ret << 8) | **sigp; | *len = (*len << 8) | **sigp; | ||||
if (ret + lenleft > (size_t)(sigend - *sigp)) { | |||||
/* Result exceeds the length of the passed array. */ | |||||
return -1; | |||||
} | |||||
(*sigp)++; | (*sigp)++; | ||||
lenleft--; | lenleft--; | ||||
} | } | ||||
if (ret < 128) { | if (*len > (size_t)(sigend - *sigp)) { | ||||
/* Result exceeds the length of the passed array. */ | |||||
return 0; | |||||
} | |||||
if (*len < 128) { | |||||
/* Not the shortest possible length encoding. */ | /* Not the shortest possible length encoding. */ | ||||
return -1; | return 0; | ||||
} | } | ||||
return ret; | return 1; | ||||
} | } | ||||
static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { | static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { | ||||
int overflow = 0; | int overflow = 0; | ||||
unsigned char ra[32] = {0}; | unsigned char ra[32] = {0}; | ||||
int rlen; | size_t rlen; | ||||
if (*sig == sigend || **sig != 0x02) { | if (*sig == sigend || **sig != 0x02) { | ||||
/* Not a primitive integer (X.690-0207 8.3.1). */ | /* Not a primitive integer (X.690-0207 8.3.1). */ | ||||
return 0; | return 0; | ||||
} | } | ||||
(*sig)++; | (*sig)++; | ||||
rlen = secp256k1_der_read_len(sig, sigend); | if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) { | ||||
if (rlen <= 0 || (*sig) + rlen > sigend) { | return 0; | ||||
} | |||||
if (rlen == 0 || *sig + rlen > sigend) { | |||||
/* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ | /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ | ||||
return 0; | return 0; | ||||
} | } | ||||
if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { | if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { | ||||
/* Excessive 0x00 padding. */ | /* Excessive 0x00 padding. */ | ||||
return 0; | return 0; | ||||
} | } | ||||
if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { | if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { | ||||
/* Excessive 0xFF padding. */ | /* Excessive 0xFF padding. */ | ||||
return 0; | return 0; | ||||
} | } | ||||
if ((**sig & 0x80) == 0x80) { | if ((**sig & 0x80) == 0x80) { | ||||
/* Negative. */ | /* Negative. */ | ||||
overflow = 1; | overflow = 1; | ||||
} | } | ||||
while (rlen > 0 && **sig == 0) { | /* There is at most one leading zero byte: | ||||
/* Skip leading zero bytes */ | * if there were two leading zero bytes, we would have failed and returned 0 | ||||
* because of excessive 0x00 padding already. */ | |||||
if (rlen > 0 && **sig == 0) { | |||||
/* Skip leading zero byte */ | |||||
rlen--; | rlen--; | ||||
(*sig)++; | (*sig)++; | ||||
} | } | ||||
if (rlen > 32) { | if (rlen > 32) { | ||||
overflow = 1; | overflow = 1; | ||||
} | } | ||||
if (!overflow) { | if (!overflow) { | ||||
memcpy(ra + 32 - rlen, *sig, rlen); | memcpy(ra + 32 - rlen, *sig, rlen); | ||||
secp256k1_scalar_set_b32(r, ra, &overflow); | secp256k1_scalar_set_b32(r, ra, &overflow); | ||||
} | } | ||||
if (overflow) { | if (overflow) { | ||||
secp256k1_scalar_set_int(r, 0); | secp256k1_scalar_set_int(r, 0); | ||||
} | } | ||||
(*sig) += rlen; | (*sig) += rlen; | ||||
return 1; | return 1; | ||||
} | } | ||||
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { | ||||
const unsigned char *sigend = sig + size; | const unsigned char *sigend = sig + size; | ||||
int rlen; | size_t rlen; | ||||
if (sig == sigend || *(sig++) != 0x30) { | if (sig == sigend || *(sig++) != 0x30) { | ||||
/* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ | /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ | ||||
return 0; | return 0; | ||||
} | } | ||||
rlen = secp256k1_der_read_len(&sig, sigend); | if (secp256k1_der_read_len(&rlen, &sig, sigend) == 0) { | ||||
if (rlen < 0 || sig + rlen > sigend) { | |||||
/* Tuple exceeds bounds */ | |||||
return 0; | return 0; | ||||
} | } | ||||
if (sig + rlen != sigend) { | if (rlen != (size_t)(sigend - sig)) { | ||||
/* Garbage after tuple. */ | /* Tuple exceeds bounds or garage after tuple. */ | ||||
return 0; | return 0; | ||||
} | } | ||||
if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { | if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { | ||||
return 0; | return 0; | ||||
} | } | ||||
if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { | if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { | ||||
return 0; | return 0; | ||||
▲ Show 20 Lines • Show All 147 Lines • Show Last 20 Lines |