aboutsummaryrefslogtreecommitdiff
path: root/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'rsa.c')
-rw-r--r--rsa.c135
1 files changed, 116 insertions, 19 deletions
diff --git a/rsa.c b/rsa.c
index a03b41a..b257604 100644
--- a/rsa.c
+++ b/rsa.c
@@ -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"
@@ -116,7 +116,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 +256,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 +455,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 +478,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 +509,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 +519,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 +529,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 +628,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 +688,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 +734,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 +751,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 +776,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: