diff options
author | Rob Austein <sra@hactrn.net> | 2015-09-02 18:35:36 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2015-09-02 18:35:36 -0400 |
commit | 12ed3abeb24bbd5d59b760640a35ead0874fd3fe (patch) | |
tree | 1dcc0db3d543e7b740238ea911b7f448c704e70b | |
parent | 55116cc564649433cf4a8515d4a37cbf00dd6199 (diff) |
Clean up excessively complicated handling of opaque types in hash and
RSA code; use simpler model (pointer to incomplete structure) used in
ECDSA code. Refactor RSA code to use shared ASN.1 routines.
-rw-r--r-- | asn1.c | 10 | ||||
-rw-r--r-- | asn1_internal.h | 19 | ||||
-rw-r--r-- | ecdsa.c | 15 | ||||
-rw-r--r-- | hal.h | 52 | ||||
-rw-r--r-- | hash.c | 123 | ||||
-rw-r--r-- | pbkdf2.c | 2 | ||||
-rw-r--r-- | rsa.c | 336 | ||||
-rw-r--r-- | tests/test-ecdsa.c | 2 | ||||
-rw-r--r-- | tests/test-hash.c | 4 | ||||
-rw-r--r-- | tests/test-rsa.c | 4 |
10 files changed, 218 insertions, 349 deletions
@@ -105,7 +105,7 @@ hal_error_t hal_asn1_encode_header(const uint8_t tag, * NULL, just return the length of what we would have encoded. */ -hal_error_t hal_asn1_encode_integer(fp_int *bn, +hal_error_t hal_asn1_encode_integer(const fp_int * const bn, uint8_t *der, size_t *der_len, const size_t der_max) { if (bn == NULL) @@ -118,11 +118,11 @@ hal_error_t hal_asn1_encode_integer(fp_int *bn, * difference between libtfm's and ASN.1's encoding of zero. */ - if (fp_cmp_d(bn, 0) == FP_LT) + if (fp_cmp_d(unconst_fp_int(bn), 0) == FP_LT) return HAL_ERROR_BAD_ARGUMENTS; - const int leading_zero = fp_iszero(bn) || (fp_count_bits(bn) & 7) == 0; - const size_t vlen = fp_unsigned_bin_size(bn) + leading_zero; + const int leading_zero = fp_iszero(bn) || (fp_count_bits(unconst_fp_int(bn)) & 7) == 0; + const size_t vlen = fp_unsigned_bin_size(unconst_fp_int(bn)) + leading_zero; hal_error_t err; size_t hlen; @@ -141,7 +141,7 @@ hal_error_t hal_asn1_encode_integer(fp_int *bn, der += hlen; if (leading_zero) *der++ = 0x00; - fp_to_unsigned_bin(bn, der); + fp_to_unsigned_bin(unconst_fp_int(bn), der); return HAL_OK; } diff --git a/asn1_internal.h b/asn1_internal.h index 9d5ab4d..f6e470f 100644 --- a/asn1_internal.h +++ b/asn1_internal.h @@ -68,6 +68,23 @@ #define ASN1_EXPLICIT_0 (ASN1_EXPLICIT_CONTEXT + 0) #define ASN1_EXPLICIT_1 (ASN1_EXPLICIT_CONTEXT + 1) +/* + * Functions to strip const qualifiers from arguments to libtfm calls + * in a relatively type-safe manner. These don't really have anything + * to do with ASN.1 per se, but all the code that needs them reads + * this header file, so this is the simplest place to put them. + */ + +static inline fp_int *unconst_fp_int(const fp_int * const arg) +{ + return (fp_int *) arg; +} + +static inline uint8_t *unconst_uint8_t(const uint8_t * const arg) +{ + return (uint8_t *) arg; +} + extern hal_error_t hal_asn1_encode_header(const uint8_t tag, const size_t value_len, uint8_t *der, size_t *der_len, const size_t der_max); @@ -76,7 +93,7 @@ extern hal_error_t hal_asn1_decode_header(const uint8_t tag, const uint8_t * const der, size_t der_max, size_t *hlen, size_t *vlen); -extern hal_error_t hal_asn1_encode_integer(fp_int *bn, +extern hal_error_t hal_asn1_encode_integer(const fp_int * const bn, uint8_t *der, size_t *der_len, const size_t der_max); extern hal_error_t hal_asn1_decode_integer(fp_int *bn, @@ -153,21 +153,6 @@ const size_t hal_ecdsa_key_t_size = sizeof(struct hal_ecdsa_key); #define lose(_code_) do { err = _code_; goto fail; } while (0) /* - * Functions to strip const qualifiers from arguments to libtfm calls - * in a relatively type-safe manner. - */ - -static inline fp_int *unconst_fp_int(const fp_int * const arg) -{ - return (fp_int *) arg; -} - -static inline uint8_t *unconst_uint8_t(const uint8_t * const arg) -{ - return (uint8_t *) arg; -} - -/* * We can't (usefully) initialize fp_int variables at compile time, so * instead we load all the curve parameters the first time anything * asks for any of them. @@ -503,6 +503,12 @@ extern hal_error_t hal_get_random(void *buffer, const size_t length); #define HAL_MAX_HASH_DIGEST_LENGTH SHA512_DIGEST_LEN /* + * Opaque driver structure for digest algorithms. + */ + +typedef struct hal_hash_driver hal_hash_driver_t; + +/* * Public information about a digest algorithm. * * The _state_length values in the descriptor and the typed opaque @@ -518,15 +524,15 @@ typedef struct { size_t hmac_state_length; const uint8_t * const digest_algorithm_id; size_t digest_algorithm_id_length; - const void *driver; + const hal_hash_driver_t *driver; } hal_hash_descriptor_t; /* - * Typed opaque pointers to internal state. + * Opaque pointers to internal state. */ -typedef struct { void *state; } hal_hash_state_t; -typedef struct { void *state; } hal_hmac_state_t; +typedef struct hal_hash_state hal_hash_state_t; +typedef struct hal_hmac_state hal_hmac_state_t; /* * Supported digest algorithms. These are one-element arrays so that @@ -549,24 +555,24 @@ extern void hal_hash_set_debug(int onoff); extern hal_error_t hal_hash_core_present(const hal_hash_descriptor_t * const descriptor); extern hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor, - hal_hash_state_t *state, + hal_hash_state_t **state, void *state_buffer, const size_t state_length); -extern hal_error_t hal_hash_update(const hal_hash_state_t state, +extern hal_error_t hal_hash_update(hal_hash_state_t *state, const uint8_t * data, const size_t length); -extern hal_error_t hal_hash_finalize(const hal_hash_state_t state, +extern hal_error_t hal_hash_finalize(hal_hash_state_t *state, uint8_t *digest, const size_t length); extern hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, - hal_hmac_state_t *state, + hal_hmac_state_t **state, void *state_buffer, const size_t state_length, const uint8_t * const key, const size_t key_length); -extern hal_error_t hal_hmac_update(const hal_hmac_state_t state, +extern hal_error_t hal_hmac_update(hal_hmac_state_t *state, const uint8_t * data, const size_t length); -extern hal_error_t hal_hmac_finalize(const hal_hmac_state_t state, +extern hal_error_t hal_hmac_finalize(hal_hmac_state_t *state, uint8_t *hmac, const size_t length); /* @@ -612,7 +618,7 @@ extern hal_error_t hal_modexp(const uint8_t * const msg, const size_t msg_len, / typedef enum { HAL_RSA_PRIVATE, HAL_RSA_PUBLIC } hal_rsa_key_type_t; -typedef struct { void *key; } hal_rsa_key_t; +typedef struct hal_rsa_key hal_rsa_key_t; extern const size_t hal_rsa_key_t_size; @@ -620,7 +626,7 @@ extern void hal_rsa_set_debug(const int onoff); extern void hal_rsa_set_blinding(const int onoff); -extern hal_error_t hal_rsa_key_load_private(hal_rsa_key_t *key, +extern hal_error_t hal_rsa_key_load_private(hal_rsa_key_t **key, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len, @@ -631,45 +637,45 @@ extern hal_error_t hal_rsa_key_load_private(hal_rsa_key_t *key, const uint8_t * const dP, const size_t dP_len, const uint8_t * const dQ, const size_t dQ_len); -extern hal_error_t hal_rsa_key_load_public(hal_rsa_key_t *key, +extern hal_error_t hal_rsa_key_load_public(hal_rsa_key_t **key, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len); -extern hal_error_t hal_rsa_key_get_type(hal_rsa_key_t key, +extern hal_error_t hal_rsa_key_get_type(const hal_rsa_key_t *key, hal_rsa_key_type_t *key_type); -extern hal_error_t hal_rsa_key_get_modulus(hal_rsa_key_t key, +extern hal_error_t hal_rsa_key_get_modulus(const hal_rsa_key_t *key, uint8_t *modulus, size_t *modulus_len, const size_t modulus_max); -extern hal_error_t hal_rsa_key_get_public_exponent(hal_rsa_key_t key, +extern hal_error_t hal_rsa_key_get_public_exponent(const hal_rsa_key_t *key, uint8_t *public_exponent, size_t *public_exponent_len, const size_t public_exponent_max); -extern void hal_rsa_key_clear(hal_rsa_key_t key); +extern void hal_rsa_key_clear(hal_rsa_key_t *key); -extern hal_error_t hal_rsa_encrypt(hal_rsa_key_t key, +extern hal_error_t hal_rsa_encrypt(const hal_rsa_key_t *key, const uint8_t * const input, const size_t input_len, uint8_t * output, const size_t output_len); -extern hal_error_t hal_rsa_decrypt(hal_rsa_key_t key, +extern hal_error_t hal_rsa_decrypt(const hal_rsa_key_t *key, const uint8_t * const input, const size_t input_len, uint8_t * output, const size_t output_len); -extern hal_error_t hal_rsa_key_gen(hal_rsa_key_t *key, +extern hal_error_t hal_rsa_key_gen(hal_rsa_key_t **key, void *keybuf, const size_t keybuf_len, const unsigned key_length, const uint8_t * const public_exponent, const size_t public_exponent_len); -extern hal_error_t hal_rsa_key_to_der(hal_rsa_key_t key, +extern hal_error_t hal_rsa_key_to_der(const hal_rsa_key_t *key, uint8_t *der, size_t *der_len, const size_t der_max); -extern size_t hal_rsa_key_to_der_len(hal_rsa_key_t key); +extern size_t hal_rsa_key_to_der_len(hal_rsa_key_t *key); -extern hal_error_t hal_rsa_key_from_der(hal_rsa_key_t *key, +extern hal_error_t hal_rsa_key_from_der(hal_rsa_key_t **key, void *keybuf, const size_t keybuf_len, const uint8_t * const der, const size_t der_len); @@ -64,7 +64,7 @@ * memory map, so it's not really worth overthinking at the moment. */ -typedef struct { +struct hal_hash_driver { size_t length_length; /* Length of the length field */ off_t block_addr; /* Where to write hash blocks */ off_t ctrl_addr; /* Control register */ @@ -73,21 +73,21 @@ typedef struct { off_t name_addr; /* Where to read core name */ char core_name[8]; /* Expected name of core */ uint8_t ctrl_mode; /* Digest mode, for cores that have modes */ -} driver_t; +}; /* * Hash state. */ -typedef struct { +struct hal_hash_state { const hal_hash_descriptor_t *descriptor; - const driver_t *driver; + const hal_hash_driver_t *driver; uint64_t msg_length_high; /* Total data hashed in this message */ uint64_t msg_length_low; /* (128 bits in SHA-512 cases) */ uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH]; /* Block we're accumulating */ size_t block_used; /* How much of the block we've used */ unsigned block_count; /* Blocks sent */ -} internal_hash_state_t; +}; /* * HMAC state. Right now this just holds the key block and a hash @@ -97,10 +97,10 @@ typedef struct { * performance boost for things like PBKDF2. */ -typedef struct { - internal_hash_state_t hash_state; /* Hash state */ +struct hal_hmac_state { + hal_hash_state_t hash_state; /* Hash state */ uint8_t keybuf[HAL_MAX_HASH_BLOCK_LENGTH]; /* HMAC key */ -} internal_hmac_state_t; +}; /* * Drivers for known digest algorithms. @@ -110,42 +110,42 @@ typedef struct { * whine if the resulting string doesn't fit into the field. */ -static const driver_t sha1_driver = { +static const hal_hash_driver_t sha1_driver = { SHA1_LENGTH_LEN, SHA1_ADDR_BLOCK, SHA1_ADDR_CTRL, SHA1_ADDR_STATUS, SHA1_ADDR_DIGEST, SHA1_ADDR_NAME0, (SHA1_NAME0 SHA1_NAME1), 0 }; -static const driver_t sha256_driver = { +static const hal_hash_driver_t sha256_driver = { SHA256_LENGTH_LEN, SHA256_ADDR_BLOCK, SHA256_ADDR_CTRL, SHA256_ADDR_STATUS, SHA256_ADDR_DIGEST, SHA256_ADDR_NAME0, (SHA256_NAME0 SHA256_NAME1), 0 }; -static const driver_t sha512_224_driver = { +static const hal_hash_driver_t sha512_224_driver = { SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST, SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1), MODE_SHA_512_224 }; -static const driver_t sha512_256_driver = { +static const hal_hash_driver_t sha512_256_driver = { SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST, SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1), MODE_SHA_512_256 }; -static const driver_t sha384_driver = { +static const hal_hash_driver_t sha384_driver = { SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST, SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1), MODE_SHA_384 }; -static const driver_t sha512_driver = { +static const hal_hash_driver_t sha512_driver = { SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST, SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1), @@ -183,42 +183,42 @@ static const uint8_t const hal_hash_descriptor_t hal_hash_sha1[1] = {{ SHA1_BLOCK_LEN, SHA1_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha1, sizeof(dalgid_sha1), &sha1_driver }}; const hal_hash_descriptor_t hal_hash_sha256[1] = {{ SHA256_BLOCK_LEN, SHA256_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha256, sizeof(dalgid_sha256), &sha256_driver }}; const hal_hash_descriptor_t hal_hash_sha512_224[1] = {{ SHA512_BLOCK_LEN, SHA512_224_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512_224, sizeof(dalgid_sha512_224), &sha512_224_driver }}; const hal_hash_descriptor_t hal_hash_sha512_256[1] = {{ SHA512_BLOCK_LEN, SHA512_256_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512_256, sizeof(dalgid_sha512_256), &sha512_256_driver }}; const hal_hash_descriptor_t hal_hash_sha384[1] = {{ SHA512_BLOCK_LEN, SHA384_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha384, sizeof(dalgid_sha384), &sha384_driver }}; const hal_hash_descriptor_t hal_hash_sha512[1] = {{ SHA512_BLOCK_LEN, SHA512_DIGEST_LEN, - sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t), + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512, sizeof(dalgid_sha512), &sha512_driver }}; @@ -242,7 +242,7 @@ void hal_hash_set_debug(int onoff) * Returns the driver pointer on success, NULL on failure. */ -static const driver_t *check_driver(const hal_hash_descriptor_t * const descriptor) +static const hal_hash_driver_t *check_driver(const hal_hash_descriptor_t * const descriptor) { return descriptor == NULL ? NULL : descriptor->driver; } @@ -253,7 +253,7 @@ static const driver_t *check_driver(const hal_hash_descriptor_t * const descript hal_error_t hal_hash_core_present(const hal_hash_descriptor_t * const descriptor) { - const driver_t * const driver = check_driver(descriptor); + const hal_hash_driver_t * const driver = check_driver(descriptor); if (driver == NULL) return HAL_ERROR_BAD_ARGUMENTS; @@ -268,13 +268,13 @@ hal_error_t hal_hash_core_present(const hal_hash_descriptor_t * const descriptor */ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor, - hal_hash_state_t *opaque_state, + hal_hash_state_t **state_, void *state_buffer, const size_t state_length) { - const driver_t * const driver = check_driver(descriptor); - internal_hash_state_t *state = state_buffer; + const hal_hash_driver_t * const driver = check_driver(descriptor); + hal_hash_state_t *state = state_buffer; - if (driver == NULL || state == NULL || opaque_state == NULL || + if (driver == NULL || state == NULL || state_ == NULL || state_length < descriptor->hash_state_length) return HAL_ERROR_BAD_ARGUMENTS; @@ -282,7 +282,7 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor, state->descriptor = descriptor; state->driver = driver; - opaque_state->state = state; + *state_ = state; return HAL_OK; } @@ -291,7 +291,7 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor, * Send one block to a core. */ -static hal_error_t hash_write_block(const internal_hash_state_t * const state) +static hal_error_t hash_write_block(hal_hash_state_t * const state) { uint8_t ctrl_cmd[4]; hal_error_t err; @@ -324,7 +324,7 @@ static hal_error_t hash_write_block(const internal_hash_state_t * const state) * Read hash result from core. */ -static hal_error_t hash_read_digest(const driver_t * const driver, +static hal_error_t hash_read_digest(const hal_hash_driver_t * const driver, uint8_t *digest, const size_t digest_length) { @@ -342,11 +342,10 @@ static hal_error_t hash_read_digest(const driver_t * const driver, * Add data to hash. */ -hal_error_t hal_hash_update(hal_hash_state_t opaque_state, /* Opaque state block */ +hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state block */ const uint8_t * const data_buffer, /* Data to be hashed */ size_t data_buffer_length) /* Length of data_buffer */ { - internal_hash_state_t *state = opaque_state.state; const uint8_t *p = data_buffer; hal_error_t err; size_t n; @@ -399,11 +398,10 @@ hal_error_t hal_hash_update(hal_hash_state_t opaque_state, /* Opaque state * Finish hash and return digest. */ -hal_error_t hal_hash_finalize(hal_hash_state_t opaque_state, /* Opaque state block */ +hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaque state block */ uint8_t *digest_buffer, /* Returned digest */ const size_t digest_buffer_length) /* Length of digest_buffer */ { - internal_hash_state_t *state = opaque_state.state; uint64_t bit_length_high, bit_length_low; hal_error_t err; uint8_t *p; @@ -479,18 +477,17 @@ hal_error_t hal_hash_finalize(hal_hash_state_t opaque_state, /* Opaqu */ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, - hal_hmac_state_t *opaque_state, + hal_hmac_state_t **state_, void *state_buffer, const size_t state_length, const uint8_t * const key, const size_t key_length) { - const driver_t * const driver = check_driver(descriptor); - internal_hmac_state_t *state = state_buffer; - internal_hash_state_t *h = &state->hash_state; - hal_hash_state_t oh; + const hal_hash_driver_t * const driver = check_driver(descriptor); + hal_hmac_state_t *state = state_buffer; + hal_hash_state_t *h = NULL; hal_error_t err; int i; - if (descriptor == NULL || driver == NULL || state == NULL || opaque_state == NULL || + if (descriptor == NULL || driver == NULL || state == NULL || state_ == NULL || state_length < descriptor->hmac_state_length) return HAL_ERROR_BAD_ARGUMENTS; @@ -506,7 +503,8 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, return HAL_ERROR_UNSUPPORTED_KEY; #endif - if ((err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK) + if ((err = hal_hash_initialize(descriptor, &h, &state->hash_state, + sizeof(state->hash_state))) != HAL_OK) return err; /* @@ -520,9 +518,10 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, if (key_length <= descriptor->block_length) memcpy(state->keybuf, key, key_length); - else if ((err = hal_hash_update(oh, key, key_length)) != HAL_OK || - (err = hal_hash_finalize(oh, state->keybuf, sizeof(state->keybuf))) != HAL_OK || - (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK) + else if ((err = hal_hash_update(h, key, key_length)) != HAL_OK || + (err = hal_hash_finalize(h, state->keybuf, sizeof(state->keybuf))) != HAL_OK || + (err = hal_hash_initialize(descriptor, &h, &state->hash_state, + sizeof(state->hash_state))) != HAL_OK) return err; /* @@ -532,7 +531,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, for (i = 0; i < descriptor->block_length; i++) state->keybuf[i] ^= HMAC_IPAD; - if ((err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK) + if ((err = hal_hash_update(h, state->keybuf, descriptor->block_length)) != HAL_OK) return err; /* @@ -551,7 +550,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, * when the hash cores support such a thing. */ - opaque_state->state = state; + *state_ = state; return HAL_OK; } @@ -560,37 +559,30 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, * Add data to HMAC. */ -hal_error_t hal_hmac_update(const hal_hmac_state_t opaque_state, +hal_error_t hal_hmac_update(hal_hmac_state_t *state, const uint8_t * data, const size_t length) { - internal_hmac_state_t *state = opaque_state.state; - internal_hash_state_t *h = &state->hash_state; - hal_hash_state_t oh = { h }; - if (state == NULL || data == NULL) return HAL_ERROR_BAD_ARGUMENTS; - return hal_hash_update(oh, data, length); + return hal_hash_update(&state->hash_state, data, length); } /* * Finish and return HMAC. */ -hal_error_t hal_hmac_finalize(const hal_hmac_state_t opaque_state, +hal_error_t hal_hmac_finalize(hal_hmac_state_t *state, uint8_t *hmac, const size_t length) { - internal_hmac_state_t *state = opaque_state.state; - internal_hash_state_t *h = &state->hash_state; - const hal_hash_descriptor_t *descriptor; - hal_hash_state_t oh = { h }; - uint8_t d[HAL_MAX_HASH_DIGEST_LENGTH]; - hal_error_t err; - if (state == NULL || hmac == NULL) return HAL_ERROR_BAD_ARGUMENTS; - descriptor = h->descriptor; + hal_hash_state_t *h = &state->hash_state; + const hal_hash_descriptor_t *descriptor = h->descriptor; + uint8_t d[HAL_MAX_HASH_DIGEST_LENGTH]; + hal_error_t err; + assert(descriptor != NULL && descriptor->digest_length <= sizeof(d)); /* @@ -598,11 +590,12 @@ hal_error_t hal_hmac_finalize(const hal_hmac_state_t opaque_state, * to get HMAC. Key was prepared for this in hal_hmac_initialize(). */ - if ((err = hal_hash_finalize(oh, d, sizeof(d))) != HAL_OK || - (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK || - (err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK || - (err = hal_hash_update(oh, d, descriptor->digest_length)) != HAL_OK || - (err = hal_hash_finalize(oh, hmac, length)) != HAL_OK) + if ((err = hal_hash_finalize(h, d, sizeof(d))) != HAL_OK || + (err = hal_hash_initialize(descriptor, &h, &state->hash_state, + sizeof(state->hash_state))) != HAL_OK || + (err = hal_hash_update(h, state->keybuf, descriptor->block_length)) != HAL_OK || + (err = hal_hash_update(h, d, descriptor->digest_length)) != HAL_OK || + (err = hal_hash_finalize(h, hmac, length)) != HAL_OK) return err; return HAL_OK; @@ -58,7 +58,7 @@ static hal_error_t do_hmac(const hal_hash_descriptor_t * const d, assert(d != NULL && pw != NULL && data != NULL && mac != NULL); uint8_t sb[d->hmac_state_length]; - hal_hmac_state_t s; + hal_hmac_state_t *s; hal_error_t err; if ((err = hal_hmac_initialize(d, &s, sb, sizeof(sb), pw, pw_len)) != HAL_OK) @@ -40,6 +40,25 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * We use "Tom's Fast Math" library for our bignum implementation. + * This particular implementation has a couple of nice features: + * + * - The code is relatively readable, thus reviewable. + * + * - The bignum representation doesn't use dynamic memory, which + * simplifies things for us. + * + * The price tag for not using dynamic memory is that libtfm has to be + * configured to know about the largest bignum one wants it to be able + * to support at compile time. This should not be a serious problem. + * + * Unfortunately, libtfm is bad about const-ification, but we want to + * hide that from our users, so our public API uses const as + * appropriate and we use inline functions to remove const constraints + * in a relatively type-safe manner before calling libtom. + */ + #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -48,6 +67,8 @@ #include <assert.h> #include "hal.h" +#include <tfm.h> +#include "asn1_internal.h" /* * Whether to use ModExp core. It works, but at the moment it's so @@ -59,22 +80,6 @@ #endif /* - * Use "Tom's Fast Math" library for our bignum implementation. This - * particular implementation has a couple of nice features: - * - * - The code is relatively readable, thus reviewable. - * - * - The bignum representation doesn't use dynamic memory, which - * simplifies things for us. - * - * The price tag for not using dynamic memory is that libtfm has to be - * configured to know about the largest bignum one wants it to be able - * to support at compile time. This should not be a serious problem. - */ - -#include <tfm.h> - -/* * Whether we want debug output. */ @@ -103,7 +108,7 @@ void hal_rsa_set_blinding(const int onoff) * can make memory allocation the caller's problem. */ -struct rsa_key { +struct hal_rsa_key { hal_rsa_key_type_t type; /* What kind of key this is */ fp_int n; /* The modulus */ fp_int e; /* Public exponent */ @@ -115,7 +120,7 @@ struct rsa_key { fp_int dQ; /* d mod (q - 1) */ }; -const size_t hal_rsa_key_t_size = sizeof(struct rsa_key); +const size_t hal_rsa_key_t_size = sizeof(hal_rsa_key_t); /* * Error handling. @@ -139,19 +144,19 @@ const size_t hal_rsa_key_t_size = sizeof(struct rsa_key); * Unpack a bignum into a byte array, with length check. */ -static hal_error_t unpack_fp(fp_int *bn, uint8_t *buffer, const size_t length) +static hal_error_t unpack_fp(const fp_int * const bn, uint8_t *buffer, const size_t length) { hal_error_t err = HAL_OK; assert(bn != NULL && buffer != NULL); - const size_t bytes = fp_unsigned_bin_size(bn); + const size_t bytes = fp_unsigned_bin_size(unconst_fp_int(bn)); if (bytes > length) lose(HAL_ERROR_RESULT_TOO_LONG); memset(buffer, 0, length); - fp_to_unsigned_bin(bn, buffer + length - bytes); + fp_to_unsigned_bin(unconst_fp_int(bn), buffer + length - bytes); fail: return err; @@ -164,7 +169,10 @@ static hal_error_t unpack_fp(fp_int *bn, uint8_t *buffer, const size_t length) * wrap result back up as a bignum. */ -static hal_error_t modexp(fp_int *msg, fp_int *exp, fp_int *mod, fp_int *res) +static hal_error_t modexp(const fp_int * const msg, + const fp_int * const exp, + const fp_int * const mod, + fp_int *res) { hal_error_t err = HAL_OK; @@ -219,10 +227,13 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) * wait for the slow FPGA implementation. */ -static hal_error_t modexp(fp_int *msg, fp_int *exp, fp_int *mod, fp_int *res) +static hal_error_t modexp(const fp_int * const msg, + const fp_int * const exp, + const fp_int * const mod, + fp_int *res) { hal_error_t err = HAL_OK; - FP_CHECK(fp_exptmod(msg, exp, mod, res)); + FP_CHECK(fp_exptmod(unconst_fp_int(msg), unconst_fp_int(exp), unconst_fp_int(mod), res)); fail: return err; } @@ -235,11 +246,11 @@ static hal_error_t modexp(fp_int *msg, fp_int *exp, fp_int *mod, fp_int *res) * try. Come back to this if it looks like a bottleneck. */ -static hal_error_t create_blinding_factors(struct rsa_key *key, fp_int *bf, fp_int *ubf) +static hal_error_t create_blinding_factors(const hal_rsa_key_t *key, fp_int *bf, fp_int *ubf) { assert(key != NULL && bf != NULL && ubf != NULL); - uint8_t rnd[fp_unsigned_bin_size(&key->n)]; + uint8_t rnd[fp_unsigned_bin_size(unconst_fp_int(&key->n))]; hal_error_t err = HAL_OK; if ((err = hal_get_random(rnd, sizeof(rnd))) != HAL_OK) @@ -252,7 +263,7 @@ static hal_error_t create_blinding_factors(struct rsa_key *key, fp_int *bf, fp_i if ((err = modexp(bf, &key->e, &key->n, bf)) != HAL_OK) goto fail; - FP_CHECK(fp_invmod(ubf, &key->n, ubf)); + FP_CHECK(fp_invmod(ubf, unconst_fp_int(&key->n), ubf)); fail: memset(rnd, 0, sizeof(rnd)); @@ -263,7 +274,7 @@ static hal_error_t create_blinding_factors(struct rsa_key *key, fp_int *bf, fp_i * RSA decryption via Chinese Remainder Theorem (Garner's formula). */ -static hal_error_t rsa_crt(struct rsa_key *key, fp_int *msg, fp_int *sig) +static hal_error_t rsa_crt(const hal_rsa_key_t *key, fp_int *msg, fp_int *sig) { assert(key != NULL && msg != NULL && sig != NULL); @@ -280,7 +291,7 @@ static hal_error_t rsa_crt(struct rsa_key *key, fp_int *msg, fp_int *sig) if (blinding) { if ((err = create_blinding_factors(key, &bf, &ubf)) != HAL_OK) goto fail; - FP_CHECK(fp_mulmod(msg, &bf, &key->n, msg)); + FP_CHECK(fp_mulmod(msg, &bf, unconst_fp_int(&key->n), msg)); } /* @@ -301,24 +312,24 @@ static hal_error_t rsa_crt(struct rsa_key *key, fp_int *msg, fp_int *sig) * once or twice doesn't help, something is very wrong. */ if (fp_cmp_d(&t, 0) == FP_LT) - fp_add(&t, &key->p, &t); + fp_add(&t, unconst_fp_int(&key->p), &t); if (fp_cmp_d(&t, 0) == FP_LT) - fp_add(&t, &key->p, &t); + fp_add(&t, unconst_fp_int(&key->p), &t); if (fp_cmp_d(&t, 0) == FP_LT) lose(HAL_ERROR_IMPOSSIBLE); /* * sig = (t * u mod p) * q + m2 */ - FP_CHECK(fp_mulmod(&t, &key->u, &key->p, &t)); - fp_mul(&t, &key->q, &t); + FP_CHECK(fp_mulmod(&t, unconst_fp_int(&key->u), unconst_fp_int(&key->p), &t)); + fp_mul(&t, unconst_fp_int(&key->q), &t); fp_add(&t, &m2, sig); /* * Unblind if necessary. */ if (blinding) - FP_CHECK(fp_mulmod(sig, &ubf, &key->n, sig)); + FP_CHECK(fp_mulmod(sig, &ubf, unconst_fp_int(&key->n), sig)); fail: fp_zero(&t); @@ -334,11 +345,10 @@ static hal_error_t rsa_crt(struct rsa_key *key, fp_int *msg, fp_int *sig) * to the caller. */ -hal_error_t hal_rsa_encrypt(hal_rsa_key_t key_, +hal_error_t hal_rsa_encrypt(const hal_rsa_key_t *key, const uint8_t * const input, const size_t input_len, uint8_t * output, const size_t output_len) { - struct rsa_key *key = key_.key; hal_error_t err = HAL_OK; if (key == NULL || input == NULL || output == NULL || input_len > output_len) @@ -348,7 +358,7 @@ hal_error_t hal_rsa_encrypt(hal_rsa_key_t key_, fp_init(&i); fp_init(&o); - fp_read_unsigned_bin(&i, (uint8_t *) input, input_len); + fp_read_unsigned_bin(&i, unconst_uint8_t(input), input_len); if ((err = modexp(&i, &key->e, &key->n, &o)) != HAL_OK || (err = unpack_fp(&o, output, output_len)) != HAL_OK) @@ -360,11 +370,10 @@ hal_error_t hal_rsa_encrypt(hal_rsa_key_t key_, return err; } -hal_error_t hal_rsa_decrypt(hal_rsa_key_t key_, +hal_error_t hal_rsa_decrypt(const hal_rsa_key_t *key, const uint8_t * const input, const size_t input_len, uint8_t * output, const size_t output_len) { - struct rsa_key *key = key_.key; hal_error_t err = HAL_OK; if (key == NULL || input == NULL || output == NULL || input_len > output_len) @@ -374,7 +383,7 @@ hal_error_t hal_rsa_decrypt(hal_rsa_key_t key_, fp_init(&i); fp_init(&o); - fp_read_unsigned_bin(&i, (uint8_t *) input, input_len); + fp_read_unsigned_bin(&i, unconst_uint8_t(input), input_len); /* * Do CRT if we have all the necessary key components, otherwise @@ -400,10 +409,10 @@ hal_error_t hal_rsa_decrypt(hal_rsa_key_t key_, * than plain old memset() eventually. */ -void hal_rsa_key_clear(hal_rsa_key_t key) +void hal_rsa_key_clear(hal_rsa_key_t *key) { - if (key.key != NULL) - memset(key.key, 0, sizeof(struct rsa_key)); + if (key != NULL) + memset(key, 0, sizeof(*key)); } /* @@ -417,7 +426,7 @@ void hal_rsa_key_clear(hal_rsa_key_t key) */ static hal_error_t load_key(const hal_rsa_key_type_t type, - hal_rsa_key_t *key_, + hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len, @@ -428,22 +437,22 @@ static hal_error_t load_key(const hal_rsa_key_type_t type, const uint8_t * const dP, const size_t dP_len, const uint8_t * const dQ, const size_t dQ_len) { - if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(struct rsa_key)) + if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(hal_rsa_key_t)) return HAL_ERROR_BAD_ARGUMENTS; memset(keybuf, 0, keybuf_len); - struct rsa_key *key = keybuf; + hal_rsa_key_t *key = keybuf; key->type = type; -#define _(x) do { fp_init(&key->x); if (x == NULL) goto fail; fp_read_unsigned_bin(&key->x, (uint8_t *) x, x##_len); } while (0) +#define _(x) do { fp_init(&key->x); if (x == NULL) goto fail; fp_read_unsigned_bin(&key->x, unconst_uint8_t(x), x##_len); } while (0) switch (type) { case HAL_RSA_PRIVATE: _(d); _(p); _(q); _(u); _(dP); _(dQ); case HAL_RSA_PUBLIC: _(n); _(e); - key_->key = key; + *key_ = key; return HAL_OK; } #undef _ @@ -457,7 +466,7 @@ static hal_error_t load_key(const hal_rsa_key_type_t type, * Public API to load_key(). */ -hal_error_t hal_rsa_key_load_private(hal_rsa_key_t *key_, +hal_error_t hal_rsa_key_load_private(hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len, @@ -473,7 +482,7 @@ hal_error_t hal_rsa_key_load_private(hal_rsa_key_t *key_, d, d_len, p, p_len, q, q_len, u, u_len, dP, dP_len, dQ, dQ_len); } -hal_error_t hal_rsa_key_load_public(hal_rsa_key_t *key_, +hal_error_t hal_rsa_key_load_public(hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len) @@ -487,11 +496,9 @@ hal_error_t hal_rsa_key_load_public(hal_rsa_key_t *key_, * Extract the key type. */ -hal_error_t hal_rsa_key_get_type(hal_rsa_key_t key_, +hal_error_t hal_rsa_key_get_type(const hal_rsa_key_t *key, hal_rsa_key_type_t *key_type) { - struct rsa_key *key = key_.key; - if (key == NULL || key_type == NULL) return HAL_ERROR_BAD_ARGUMENTS; @@ -503,15 +510,15 @@ hal_error_t hal_rsa_key_get_type(hal_rsa_key_t key_, * Extract public key components. */ -static hal_error_t extract_component(hal_rsa_key_t key_, const size_t offset, +static hal_error_t extract_component(const hal_rsa_key_t *key, const size_t offset, uint8_t *res, size_t *res_len, const size_t res_max) { - if (key_.key == NULL) + if (key == NULL) return HAL_ERROR_BAD_ARGUMENTS; - fp_int *bn = (fp_int *) (((uint8_t *) key_.key) + offset); + const fp_int * const bn = (const fp_int *) (((const uint8_t *) key) + offset); - const size_t len = fp_unsigned_bin_size(bn); + const size_t len = fp_unsigned_bin_size(unconst_fp_int(bn)); if (res_len != NULL) *res_len = len; @@ -523,20 +530,20 @@ static hal_error_t extract_component(hal_rsa_key_t key_, const size_t offset, return HAL_ERROR_RESULT_TOO_LONG; memset(res, 0, res_max); - fp_to_unsigned_bin(bn, res); + fp_to_unsigned_bin(unconst_fp_int(bn), res); return HAL_OK; } -hal_error_t hal_rsa_key_get_modulus(hal_rsa_key_t key_, +hal_error_t hal_rsa_key_get_modulus(const hal_rsa_key_t *key, uint8_t *res, size_t *res_len, const size_t res_max) { - return extract_component(key_, offsetof(struct rsa_key, n), res, res_len, res_max); + return extract_component(key, offsetof(hal_rsa_key_t, n), res, res_len, res_max); } -hal_error_t hal_rsa_key_get_public_exponent(hal_rsa_key_t key_, +hal_error_t hal_rsa_key_get_public_exponent(const hal_rsa_key_t *key, uint8_t *res, size_t *res_len, const size_t res_max) { - return extract_component(key_, offsetof(struct rsa_key, e), res, res_len, res_max); + return extract_component(key, offsetof(hal_rsa_key_t, e), res, res_len, res_max); } /* @@ -547,7 +554,9 @@ hal_error_t hal_rsa_key_get_public_exponent(hal_rsa_key_t key_, * which result - 1 is relatively prime with respect to e. */ -static hal_error_t find_prime(unsigned prime_length, fp_int *e, fp_int *result) +static hal_error_t find_prime(const unsigned prime_length, + const fp_int * const e, + fp_int *result) { uint8_t buffer[prime_length]; hal_error_t err; @@ -563,7 +572,7 @@ static hal_error_t find_prime(unsigned prime_length, fp_int *e, fp_int *result) fp_read_unsigned_bin(result, buffer, sizeof(buffer)); } while (!fp_isprime(result) || - (fp_sub_d(result, 1, &t), fp_gcd(&t, e, &t), fp_cmp_d(&t, 1) != FP_EQ)); + (fp_sub_d(result, 1, &t), fp_gcd(&t, unconst_fp_int(e), &t), fp_cmp_d(&t, 1) != FP_EQ)); fp_zero(&t); return HAL_OK; @@ -573,16 +582,16 @@ static hal_error_t find_prime(unsigned prime_length, fp_int *e, fp_int *result) * Generate a new RSA keypair. */ -hal_error_t hal_rsa_key_gen(hal_rsa_key_t *key_, +hal_error_t hal_rsa_key_gen(hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const unsigned key_length, const uint8_t * const public_exponent, const size_t public_exponent_len) { - struct rsa_key *key = keybuf; + hal_rsa_key_t *key = keybuf; hal_error_t err = HAL_OK; fp_int p_1, q_1; - if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(struct rsa_key)) + if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(hal_rsa_key_t)) return HAL_ERROR_BAD_ARGUMENTS; memset(keybuf, 0, keybuf_len); @@ -616,7 +625,7 @@ hal_error_t hal_rsa_key_gen(hal_rsa_key_t *key_, FP_CHECK(fp_mod(&key->d, &q_1, &key->dQ)); /* dQ = d % (q-1) */ FP_CHECK(fp_invmod(&key->q, &key->p, &key->u)); /* u = (1/q) % p */ - key_->key = key; + *key_ = key; /* Fall through to cleanup */ @@ -629,19 +638,9 @@ hal_error_t hal_rsa_key_gen(hal_rsa_key_t *key_, } /* - * Minimal ASN.1 encoding and decoding for private keys. This is NOT - * a general-purpose ASN.1 implementation, just enough to read and - * write PKCS #1.5 RSAPrivateKey syntax (RFC 2313 section 7.2). + * Just enough ASN.1 to read and write PKCS #1.5 RSAPrivateKey syntax + * (RFC 2313 section 7.2). * - * If at some later date we need a full ASN.1 implementation we'll add - * it as (a) separate library module(s), but for now the goal is just - * to let us serialize private keys for internal use and debugging. - */ - -#define ASN1_INTEGER 0x02 -#define ASN1_SEQUENCE 0x30 - -/* * RSAPrivateKey fields in the required order. */ @@ -656,139 +655,9 @@ hal_error_t hal_rsa_key_gen(hal_rsa_key_t *key_, _(&key->dQ); \ _(&key->u); -static size_t count_length(size_t length) -{ - size_t result = 1; - - if (length >= 128) - for (; length > 0; length >>= 8) - result++; - - return result; -} - -static void encode_length(size_t length, size_t length_len, uint8_t *der) -{ - assert(der != NULL && length_len > 0 && length_len < 128); - - if (length < 128) { - assert(length_len == 1); - *der = (uint8_t) length; - } - - else { - *der = 0x80 | (uint8_t) --length_len; - while (length > 0 && length_len > 0) { - der[length_len--] = (uint8_t) (length & 0xFF); - length >>= 8; - } - assert(length == 0 && length_len == 0); - } -} - -static hal_error_t decode_header(const uint8_t tag, - const uint8_t * const der, size_t der_max, - size_t *hlen, size_t *vlen) -{ - assert(der != NULL && hlen != NULL && vlen != NULL); - - if (der_max < 2 || der[0] != tag) - return HAL_ERROR_ASN1_PARSE_FAILED; - - if ((der[1] & 0x80) == 0) { - *hlen = 2; - *vlen = der[1]; - } - - else { - *hlen = 2 + (der[1] & 0x7F); - *vlen = 0; - - if (*hlen > der_max) - return HAL_ERROR_ASN1_PARSE_FAILED; - - for (size_t i = 2; i < *hlen; i++) - *vlen = (*vlen << 8) + der[i]; - } - - if (*hlen + *vlen > der_max) - return HAL_ERROR_ASN1_PARSE_FAILED; - - return HAL_OK; -} - -static hal_error_t encode_integer(fp_int *bn, - uint8_t *der, size_t *der_len, const size_t der_max) -{ - if (bn == NULL || der_len == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - /* - * Calculate length. Need to pad data with a leading zero if most - * significant bit is set, to avoid flipping ASN.1 sign bit. If - * caller didn't supply a buffer, just return the total length. - */ - - const int cmp = fp_cmp_d(bn, 0); - - if (cmp != FP_EQ && cmp != FP_GT) - return HAL_ERROR_BAD_ARGUMENTS; - - const int leading_zero = (cmp == FP_EQ || (fp_count_bits(bn) & 7) == 0); - const size_t data_len = fp_unsigned_bin_size(bn) + leading_zero; - const size_t tag_len = 1; - const size_t length_len = count_length(data_len); - const size_t total_len = tag_len + length_len + data_len; - - *der_len = total_len; - - if (der == NULL) - return HAL_OK; - - if (total_len > der_max) - return HAL_ERROR_RESULT_TOO_LONG; - - /* - * Now encode. - */ - - *der++ = ASN1_INTEGER; - encode_length(data_len, length_len, der); - der += length_len; - if (leading_zero) - *der++ = 0x00; - fp_to_unsigned_bin(bn, der); - - return HAL_OK; -} - -static hal_error_t decode_integer(fp_int *bn, - const uint8_t * const der, size_t *der_len, const size_t der_max) -{ - if (bn == NULL || der == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - hal_error_t err; - size_t hlen, vlen; - - if ((err = decode_header(ASN1_INTEGER, der, der_max, &hlen, &vlen)) != HAL_OK) - return err; - - if (der_len != NULL) - *der_len = hlen + vlen; - - if (vlen < 1 || (der[hlen] & 0x80) != 0x00) - return HAL_ERROR_ASN1_PARSE_FAILED; - - fp_init(bn); - fp_read_unsigned_bin(bn, (uint8_t *) der + hlen, vlen); - return HAL_OK; -} - -hal_error_t hal_rsa_key_to_der(hal_rsa_key_t key_, +hal_error_t hal_rsa_key_to_der(const hal_rsa_key_t *key, uint8_t *der, size_t *der_len, const size_t der_max) { - struct rsa_key *key = key_.key; hal_error_t err = HAL_OK; if (key == NULL || der_len == NULL || key->type != HAL_RSA_PRIVATE) @@ -798,65 +667,64 @@ hal_error_t hal_rsa_key_to_der(hal_rsa_key_t key_, fp_zero(&version); /* - * Calculate length. + * Calculate data length. */ - size_t data_len = 0; + size_t vlen = 0; -#define _(x) { size_t i; if ((err = encode_integer(x, NULL, &i, der_max - data_len)) != HAL_OK) return err; data_len += i; } +#define _(x) { size_t i; if ((err = hal_asn1_encode_integer(x, NULL, &i, der_max - vlen)) != HAL_OK) return err; vlen += i; } RSAPrivateKey_fields; #undef _ - const size_t tag_len = 1; - const size_t length_len = count_length(data_len); - const size_t total_len = tag_len + length_len + data_len; + /* + * Encode header. + */ + + if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, der_len, der_max)) != HAL_OK) + return err; - *der_len = total_len; + const size_t hlen = *der_len; + *der_len += vlen; if (der == NULL) return HAL_OK; - if (total_len > der_max) - return HAL_ERROR_RESULT_TOO_LONG; - /* - * Now encode. + * Encode data. */ - *der++ = ASN1_SEQUENCE; - encode_length(data_len, length_len, der); - der += length_len; + der += hlen; -#define _(x) { size_t i; if ((err = encode_integer(x, der, &i, data_len)) != HAL_OK) return err; der += i; data_len -= i; } +#define _(x) { size_t i; if ((err = hal_asn1_encode_integer(x, der, &i, vlen)) != HAL_OK) return err; der += i; vlen -= i; } RSAPrivateKey_fields; #undef _ return HAL_OK; } -size_t hal_rsa_key_to_der_len(hal_rsa_key_t key_) +size_t hal_rsa_key_to_der_len(hal_rsa_key_t *key) { size_t len = 0; - return hal_rsa_key_to_der(key_, NULL, &len, 0) == HAL_OK ? len : 0; + return hal_rsa_key_to_der(key, NULL, &len, 0) == HAL_OK ? len : 0; } -hal_error_t hal_rsa_key_from_der(hal_rsa_key_t *key_, +hal_error_t hal_rsa_key_from_der(hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const uint8_t *der, const size_t der_len) { - if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(struct rsa_key) || der == NULL) + if (key_ == NULL || keybuf == NULL || keybuf_len < sizeof(hal_rsa_key_t) || der == NULL) return HAL_ERROR_BAD_ARGUMENTS; memset(keybuf, 0, keybuf_len); - struct rsa_key *key = keybuf; + hal_rsa_key_t *key = keybuf; key->type = HAL_RSA_PRIVATE; hal_error_t err = HAL_OK; size_t hlen, vlen; - if ((err = decode_header(ASN1_SEQUENCE, der, der_len, &hlen, &vlen)) != HAL_OK) + if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, der, der_len, &hlen, &vlen)) != HAL_OK) return err; der += hlen; @@ -864,14 +732,14 @@ hal_error_t hal_rsa_key_from_der(hal_rsa_key_t *key_, fp_int version; fp_init(&version); -#define _(x) { size_t i; if ((err = decode_integer(x, der, &i, vlen)) != HAL_OK) return err; der += i; vlen -= i; } +#define _(x) { size_t i; if ((err = hal_asn1_decode_integer(x, der, &i, vlen)) != HAL_OK) return err; der += i; vlen -= i; } RSAPrivateKey_fields; #undef _ if (fp_cmp_d(&version, 0) != FP_EQ) return HAL_ERROR_ASN1_PARSE_FAILED; - key_->key = key; + *key_ = key; return HAL_OK; } diff --git a/tests/test-ecdsa.c b/tests/test-ecdsa.c index d57b440..d41a54d 100644 --- a/tests/test-ecdsa.c +++ b/tests/test-ecdsa.c @@ -227,7 +227,7 @@ static int test_keygen_sign_verify(const hal_ecdsa_curve_t curve) { const uint8_t plaintext[] = "So long, and thanks..."; uint8_t statebuf[hash_descriptor->hash_state_length]; - hal_hash_state_t state = { NULL }; + hal_hash_state_t *state = NULL; if ((err = hal_hash_initialize(hash_descriptor, &state, statebuf, sizeof(statebuf))) != HAL_OK || (err = hal_hash_update(state, plaintext, strlen((const char *) plaintext))) != HAL_OK || diff --git a/tests/test-hash.c b/tests/test-hash.c index befdf02..144b1b9 100644 --- a/tests/test-hash.c +++ b/tests/test-hash.c @@ -533,7 +533,7 @@ static int _test_hash(const hal_hash_descriptor_t * const descriptor, const char * const label) { uint8_t statebuf[512], digest[512]; - hal_hash_state_t state; + hal_hash_state_t *state = NULL; hal_error_t err; assert(descriptor != NULL && data != NULL && result != NULL && label != NULL); @@ -597,7 +597,7 @@ static int _test_hmac(const hal_hash_descriptor_t * const descriptor, const char * const label) { uint8_t statebuf[1024], digest[512]; - hal_hmac_state_t state; + hal_hmac_state_t *state = NULL; hal_error_t err; assert(descriptor != NULL && data != NULL && result != NULL && label != NULL); diff --git a/tests/test-rsa.c b/tests/test-rsa.c index 0fd2002..0751189 100644 --- a/tests/test-rsa.c +++ b/tests/test-rsa.c @@ -88,7 +88,7 @@ static int test_decrypt(const char * const kind, const rsa_tc_t * const tc) printf("%s test for %lu-bit RSA key\n", kind, (unsigned long) tc->size); uint8_t keybuf[hal_rsa_key_t_size]; - hal_rsa_key_t key = { NULL }; + hal_rsa_key_t *key = NULL; hal_error_t err = HAL_OK; if ((err = hal_rsa_key_load_private(&key, @@ -130,7 +130,7 @@ static int test_gen(const char * const kind, const rsa_tc_t * const tc) char fn[sizeof("test-rsa-key-xxxxxx.der")]; uint8_t keybuf1[hal_rsa_key_t_size], keybuf2[hal_rsa_key_t_size]; - hal_rsa_key_t key1 = { NULL }, key2 = { NULL }; + hal_rsa_key_t *key1 = NULL, *key2 = NULL; hal_error_t err = HAL_OK; FILE *f; |