/* * Copyright (c) 2016 Thomas Pornin * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef BR_BEARSSL_EC_H__ #define BR_BEARSSL_EC_H__ #include #include /* * Elliptic Curves * --------------- * * ECDSA signatures have two standard formats, called "raw" and "asn1". * Internally, such a signature is a pair of modular integers (r,s). * The "raw" format is the concatenation of the unsigned big-endian * encodings of these two integers, possibly left-padded with zeros so * that they have the same encoded length. The "asn1" format is the * DER encoding of an ASN.1 structure that contains the two integer * values: * * ECDSASignature ::= SEQUENCE { * r INTEGER, * s INTEGER * } * * Low-level implementations defined here work on the "raw" format. * Conversion functions are provided. * * Note that for a given signature, the "raw" format is not fully * deterministic, in that it does not enforce a minimal common length. * The functions below MUST ensure, when producing signatures, that * the signature length never exceeds 2*qlen, where qlen is the length, * in bytes, of the minimal unsigned big-endian encoding of the curve * subgroup order. * * Conversion of a "raw" format signature into "asn1" may enlarge a * signature by no more than 9 bytes for all supported curves. */ /* * Standard curve ID. These ID are equal to the assigned numerical * identifiers assigned to these curves for TLS: * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 */ #define BR_EC_sect163k1 1 #define BR_EC_sect163r1 2 #define BR_EC_sect163r2 3 #define BR_EC_sect193r1 4 #define BR_EC_sect193r2 5 #define BR_EC_sect233k1 6 #define BR_EC_sect233r1 7 #define BR_EC_sect239k1 8 #define BR_EC_sect283k1 9 #define BR_EC_sect283r1 10 #define BR_EC_sect409k1 11 #define BR_EC_sect409r1 12 #define BR_EC_sect571k1 13 #define BR_EC_sect571r1 14 #define BR_EC_secp160k1 15 #define BR_EC_secp160r1 16 #define BR_EC_secp160r2 17 #define BR_EC_secp192k1 18 #define BR_EC_secp192r1 19 #define BR_EC_secp224k1 20 #define BR_EC_secp224r1 21 #define BR_EC_secp256k1 22 #define BR_EC_secp256r1 23 #define BR_EC_secp384r1 24 #define BR_EC_secp521r1 25 #define BR_EC_brainpoolP256r1 26 #define BR_EC_brainpoolP384r1 27 #define BR_EC_brainpoolP512r1 28 /* * Structure for an EC public key. */ typedef struct { int curve; unsigned char *q; size_t qlen; } br_ec_public_key; /* * Structure for an EC private key. */ typedef struct { int curve; unsigned char *x; size_t xlen; } br_ec_private_key; /* * Type for an EC implementation. * * supported_curves * Bit mask for supported curves: if curve 'id' is supported, then * bit '1 << id' is set. * * generator * Get a pointer to the conventional generator for a given curve. * * order * Get a pointer to the curve order (minimal unsigned big-endian * encoding). * * mul * Compute x*G. Provided point G (encoded size Glen) must be valid and * distinct from the point at infinity. 'x' must be non-zero and less * than the curve order. On error, 0 is returned; an invalid G (or * point at infinity) is always detected, as well as a case of x = 0. * However, if x is a non-zero multiple of the curve order, then it is * not guaranteed that an error is reported. * * muladd * compute x*A+y*B, result being written over A. Points and multipliers * must fulfill the same conditions as for mul(). */ typedef struct { uint32_t supported_curves; const unsigned char *(*generator)(int curve, size_t *len); const unsigned char *(*order)(int curve, size_t *len); uint32_t (*mul)(unsigned char *G, size_t Glen, const unsigned char *x, size_t xlen, int curve); uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len, const unsigned char *x, size_t xlen, const unsigned char *y, size_t ylen, int curve); } br_ec_impl; /* * The 'i31' implementation for elliptic curves. It supports secp256r1, * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). */ extern const br_ec_impl br_ec_prime_i31; /* * Convert a signature from "raw" to "asn1". Conversion is done "in * place" and the new length is returned. Conversion may enlarge the * signature, but by no more than 9 bytes at most. On error, 0 is * returned (error conditions include an odd raw signature length, or an * oversized integer). */ size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len); /* * Convert a signature from "asn1" to "raw". Conversion is done "in * place" and the new length is returned. Conversion in that direction * always reduced signature length. On error, 0 is returned (error * conditions include an invalid signature format or an oversized * integer). */ size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len); /* * Type for an ECDSA signer function. A pointer to the EC implementation * is provided. The hash value is assumed to have the length inferred * from the designated hash function class. * * Signature is written in the buffer pointed to by 'sig', and the length * (in bytes) is returned. On error, nothing is written in the buffer, * and 0 is returned. * * The signature format is either "raw" or "asn1", depending on the * implementation; maximum length is predictable from the implemented * curve: * * curve raw asn1 * NIST P-256 64 72 * NIST P-384 96 104 * NIST P-521 132 139 */ typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl, const br_hash_class *hf, const void *hash_value, const br_ec_private_key *sk, void *sig); /* * Verify ECDSA signature. Returned value is 1 on success, 0 on error. */ typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl, const void *hash, size_t hash_len, const br_ec_public_key *pk, const void *sig, size_t sig_len); /* * ECDSA implementation using the "i31" integers. */ size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, const br_hash_class *hf, const void *hash_value, const br_ec_private_key *sk, void *sig); size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl, const br_hash_class *hf, const void *hash_value, const br_ec_private_key *sk, void *sig); uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, const void *hash, size_t hash_len, const br_ec_public_key *pk, const void *sig, size_t sig_len); uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, const void *hash, size_t hash_len, const br_ec_public_key *pk, const void *sig, size_t sig_len); #endif