diff options
Diffstat (limited to 'rsa.c')
-rw-r--r-- | rsa.c | 139 |
1 files changed, 120 insertions, 19 deletions
@@ -73,7 +73,7 @@ #include <assert.h> #include "hal.h" -#include "verilog_constants.h" +#include "hal_internal.h" #include <tfm.h> #include "asn1_internal.h" @@ -86,6 +86,10 @@ #define HAL_RSA_USE_MODEXP 1 #endif +#ifdef RPC_CLIENT +#define hal_get_random(core, buffer, length) hal_rpc_get_random(buffer, length) +#endif + /* * Whether we want debug output. */ @@ -116,7 +120,7 @@ void hal_rsa_set_blinding(const int onoff) */ struct hal_rsa_key { - hal_rsa_key_type_t type; /* What kind of key this is */ + hal_key_type_t type; /* What kind of key this is */ fp_int n[1]; /* The modulus */ fp_int e[1]; /* Public exponent */ fp_int d[1]; /* Private exponent */ @@ -256,7 +260,8 @@ 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(const fp_int * const msg, +static hal_error_t modexp(const hal_core_t *core, /* ignored */ + const fp_int * const msg, const fp_int * const exp, const fp_int * const mod, fp_int *res) @@ -454,7 +459,7 @@ void hal_rsa_key_clear(hal_rsa_key_t *key) * calculate everything else from them. */ -static hal_error_t load_key(const hal_rsa_key_type_t type, +static hal_error_t load_key(const hal_key_type_t type, hal_rsa_key_t **key_, void *keybuf, const size_t keybuf_len, const uint8_t * const n, const size_t n_len, @@ -477,12 +482,14 @@ static hal_error_t load_key(const hal_rsa_key_type_t type, #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: + case HAL_KEY_TYPE_RSA_PRIVATE: _(d); _(p); _(q); _(u); _(dP); _(dQ); - case HAL_RSA_PUBLIC: + case HAL_KEY_TYPE_RSA_PUBLIC: _(n); _(e); *key_ = key; return HAL_OK; + default: + goto fail; } #undef _ @@ -506,7 +513,7 @@ 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) { - return load_key(HAL_RSA_PRIVATE, key_, keybuf, keybuf_len, + return load_key(HAL_KEY_TYPE_RSA_PRIVATE, key_, keybuf, keybuf_len, n, n_len, e, e_len, d, d_len, p, p_len, q, q_len, u, u_len, dP, dP_len, dQ, dQ_len); } @@ -516,7 +523,7 @@ hal_error_t hal_rsa_key_load_public(hal_rsa_key_t **key_, const uint8_t * const n, const size_t n_len, const uint8_t * const e, const size_t e_len) { - return load_key(HAL_RSA_PUBLIC, key_, keybuf, keybuf_len, + return load_key(HAL_KEY_TYPE_RSA_PUBLIC, key_, keybuf, keybuf_len, n, n_len, e, e_len, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0); } @@ -526,7 +533,7 @@ hal_error_t hal_rsa_key_load_public(hal_rsa_key_t **key_, */ hal_error_t hal_rsa_key_get_type(const hal_rsa_key_t * const key, - hal_rsa_key_type_t *key_type) + hal_key_type_t *key_type) { if (key == NULL || key_type == NULL) return HAL_ERROR_BAD_ARGUMENTS; @@ -625,7 +632,7 @@ hal_error_t hal_rsa_key_gen(const hal_core_t *core, return HAL_ERROR_BAD_ARGUMENTS; memset(keybuf, 0, keybuf_len); - key->type = HAL_RSA_PRIVATE; + key->type = HAL_KEY_TYPE_RSA_PRIVATE; fp_read_unsigned_bin(key->e, (uint8_t *) public_exponent, public_exponent_len); if (key_length < bitsToBytes(1024) || key_length > bitsToBytes(8192)) @@ -685,12 +692,12 @@ hal_error_t hal_rsa_key_gen(const hal_core_t *core, _(key->dQ); \ _(key->u); -hal_error_t hal_rsa_key_to_der(const hal_rsa_key_t * const key, - uint8_t *der, size_t *der_len, const size_t der_max) +hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key, + uint8_t *der, size_t *der_len, const size_t der_max) { hal_error_t err = HAL_OK; - if (key == NULL || der_len == NULL || key->type != HAL_RSA_PRIVATE) + if (key == NULL || der_len == NULL || key->type != HAL_KEY_TYPE_RSA_PRIVATE) return HAL_ERROR_BAD_ARGUMENTS; fp_int version[1] = INIT_FP_INT; @@ -731,15 +738,15 @@ hal_error_t hal_rsa_key_to_der(const hal_rsa_key_t * const key, return HAL_OK; } -size_t hal_rsa_key_to_der_len(const hal_rsa_key_t * const key) +size_t hal_rsa_private_key_to_der_len(const hal_rsa_key_t * const key) { size_t len = 0; - return hal_rsa_key_to_der(key, NULL, &len, 0) == HAL_OK ? len : 0; + return hal_rsa_private_key_to_der(key, NULL, &len, 0) == HAL_OK ? len : 0; } -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) +hal_error_t hal_rsa_private_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(hal_rsa_key_t) || der == NULL) return HAL_ERROR_BAD_ARGUMENTS; @@ -748,7 +755,7 @@ hal_error_t hal_rsa_key_from_der(hal_rsa_key_t **key_, hal_rsa_key_t *key = keybuf; - key->type = HAL_RSA_PRIVATE; + key->type = HAL_KEY_TYPE_RSA_PRIVATE; hal_error_t err = HAL_OK; size_t hlen, vlen; @@ -773,6 +780,100 @@ hal_error_t hal_rsa_key_from_der(hal_rsa_key_t **key_, } /* + * ASN.1 public keys in SubjectPublicKeyInfo form, see RFCs 2313, 4055, and 5280. + */ + +static const uint8_t oid_rsaEncryption[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; + +hal_error_t hal_rsa_public_key_to_der(const hal_rsa_key_t * const key, + uint8_t *der, size_t *der_len, const size_t der_max) +{ + if (key == NULL || (key->type != HAL_KEY_TYPE_RSA_PRIVATE && + key->type != HAL_KEY_TYPE_RSA_PUBLIC)) + return HAL_ERROR_BAD_ARGUMENTS; + + size_t hlen, n_len, e_len; + hal_error_t err; + + if ((err = hal_asn1_encode_integer(key->n, NULL, &n_len, 0)) != HAL_OK || + (err = hal_asn1_encode_integer(key->e, NULL, &e_len, 0)) != HAL_OK) + return err; + + const size_t vlen = n_len + e_len; + + if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max)) != HAL_OK) + return err; + + if (der != NULL) { + uint8_t * const n_out = der + hlen; + uint8_t * const e_out = n_out + n_len; + + if ((err = hal_asn1_encode_integer(key->n, n_out, NULL, der + der_max - n_out)) != HAL_OK || + (err = hal_asn1_encode_integer(key->e, e_out, NULL, der + der_max - e_out)) != HAL_OK) + return err; + } + + return hal_asn1_encode_spki(oid_rsaEncryption, sizeof(oid_rsaEncryption), + NULL, 0, der, hlen + vlen, + der, der_len, der_max); + +} + +size_t hal_rsa_public_key_to_der_len(const hal_rsa_key_t * const key) +{ + size_t len = 0; + return hal_rsa_public_key_to_der(key, NULL, &len, 0) == HAL_OK ? len : 0; +} + +hal_error_t hal_rsa_public_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) +{ + hal_rsa_key_t *key = keybuf; + + if (key_ == NULL || key == NULL || keybuf_len < sizeof(*key) || der == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + memset(keybuf, 0, keybuf_len); + + key->type = HAL_KEY_TYPE_RSA_PUBLIC; + + const uint8_t *alg_oid = NULL, *null = NULL, *pubkey = NULL; + size_t alg_oid_len, null_len, pubkey_len; + hal_error_t err; + + if ((err = hal_asn1_decode_spki(&alg_oid, &alg_oid_len, &null, &null_len, &pubkey, &pubkey_len, der, der_len)) != HAL_OK) + return err; + + if (null != NULL || null_len != 0 || alg_oid == NULL || + alg_oid_len != sizeof(oid_rsaEncryption) || memcmp(alg_oid, oid_rsaEncryption, alg_oid_len) != 0) + return HAL_ERROR_ASN1_PARSE_FAILED; + + size_t len, hlen, vlen; + + if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, pubkey, pubkey_len, &hlen, &vlen)) != HAL_OK) + return err; + + const uint8_t * const pubkey_end = pubkey + hlen + vlen; + const uint8_t *d = pubkey + hlen; + + if ((err = hal_asn1_decode_integer(key->n, d, &len, pubkey_end - d)) != HAL_OK) + return err; + d += len; + + if ((err = hal_asn1_decode_integer(key->e, d, &len, pubkey_end - d)) != HAL_OK) + return err; + d += len; + + if (d != pubkey_end) + return HAL_ERROR_ASN1_PARSE_FAILED; + + *key_ = key; + + return HAL_OK; +} + +/* * Local variables: * indent-tabs-mode: nil * End: |