[Cryptech-Commits] [sw/libhal] 03/14: PKCS #8 code for RSA and ECDSA.

git at cryptech.is git at cryptech.is
Thu Apr 6 23:38:02 UTC 2017


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch pkcs8
in repository sw/libhal.

commit 33694de72d8a1c5714bea76ed70c755b5bb64a3e
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Mon Apr 3 01:41:35 2017 -0400

    PKCS #8 code for RSA and ECDSA.
    
    Compiles, not yet tested.  Existing tests need conversion to PKCS #8
    before we can do anything useful with this.
    
    Once everything uses PKCS #8 instead of algorithm-specific formats, we
    can revisit API issues like whether hal_rpc_pkey_load() should still
    be taking `type` and `curve` arguments.
---
 asn1.c          |  37 +++++++++----
 asn1_internal.h |  14 +++++
 ecdsa.c         | 164 ++++++++++++++++++++++++--------------------------------
 rsa.c           |  54 +++++++++++--------
 4 files changed, 143 insertions(+), 126 deletions(-)

diff --git a/asn1.c b/asn1.c
index 66a1748..100dc3c 100644
--- a/asn1.c
+++ b/asn1.c
@@ -58,6 +58,16 @@
 #define INIT_FP_INT     {{{0}}}
 
 /*
+ * Algorithm OIDs used in SPKI and PKCS #8.
+ */
+
+const uint8_t hal_asn1_oid_rsaEncryption[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
+const size_t  hal_asn1_oid_rsaEncryption_len = sizeof(hal_asn1_oid_rsaEncryption);
+
+const uint8_t hal_asn1_oid_ecPublicKey[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
+const size_t  hal_asn1_oid_ecPublicKey_len = sizeof(hal_asn1_oid_ecPublicKey);
+
+/*
  * Encode tag and length fields of an ASN.1 object.
  *
  * Sets *der_len to the size of of the ASN.1 header (tag and length
@@ -556,8 +566,7 @@ hal_error_t hal_asn1_decode_pkcs8_privatekeyinfo(const uint8_t **alg_oid,   size
                                                  const uint8_t **privkey,   size_t *privkey_len,
                                                  const uint8_t *const der,  const size_t der_len)
 {
-  if (alg_oid == NULL || alg_oid_len == NULL || curve_oid == NULL || curve_oid_len == NULL ||
-      privkey == NULL || privkey_len == NULL || der == NULL)
+  if (der == NULL)
     return HAL_ERROR_BAD_ARGUMENTS;
 
   const uint8_t * const der_end = der + der_len;
@@ -591,12 +600,16 @@ hal_error_t hal_asn1_decode_pkcs8_privatekeyinfo(const uint8_t **alg_oid,   size
   d += hlen;
   if (vlen > algid_end - d)
     return HAL_ERROR_ASN1_PARSE_FAILED;
-  *alg_oid = d;
-  *alg_oid_len = vlen;
+  if (alg_oid != NULL)
+    *alg_oid = d;
+  if (alg_oid_len != NULL)
+    *alg_oid_len = vlen;
   d += vlen;
 
-  *curve_oid = NULL;
-  *curve_oid_len = 0;
+  if (curve_oid != NULL)
+    *curve_oid = NULL;
+  if (curve_oid_len != NULL)
+    *curve_oid_len = 0;
 
   if (d < algid_end) {
     switch (*d) {
@@ -607,8 +620,10 @@ hal_error_t hal_asn1_decode_pkcs8_privatekeyinfo(const uint8_t **alg_oid,   size
       d += hlen;
       if (vlen > algid_end - d)
         return HAL_ERROR_ASN1_PARSE_FAILED;
-      *curve_oid = d;
-      *curve_oid_len = vlen;
+      if (curve_oid != NULL)
+        *curve_oid = d;
+      if (curve_oid_len != NULL)
+        *curve_oid_len = vlen;
       d += vlen;
       break;
 
@@ -632,8 +647,10 @@ hal_error_t hal_asn1_decode_pkcs8_privatekeyinfo(const uint8_t **alg_oid,   size
   d += hlen;
   if (vlen >= algid_end - d)
     return HAL_ERROR_ASN1_PARSE_FAILED;
-  *privkey = d;
-  *privkey_len = vlen;
+  if (privkey != NULL)
+    *privkey = d;
+  if (privkey_len != NULL)
+    *privkey_len = vlen;
   d += vlen;
 
   if (d != der_end)
diff --git a/asn1_internal.h b/asn1_internal.h
index 01ffc22..c337d4b 100644
--- a/asn1_internal.h
+++ b/asn1_internal.h
@@ -89,6 +89,20 @@ static inline uint8_t *unconst_uint8_t(const uint8_t * const arg)
   return (uint8_t *) arg;
 }
 
+/*
+ * OIDs.
+ */
+
+extern const uint8_t hal_asn1_oid_rsaEncryption[];
+extern const size_t  hal_asn1_oid_rsaEncryption_len;
+
+extern const uint8_t hal_asn1_oid_ecPublicKey[];
+extern const size_t  hal_asn1_oid_ecPublicKey_len;
+
+/*
+ * Transcoding functions.
+ */
+
 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);
diff --git a/ecdsa.c b/ecdsa.c
index d654a78..3fa720c 100644
--- a/ecdsa.c
+++ b/ecdsa.c
@@ -833,44 +833,6 @@ static hal_error_t verilog_point_pick_random(const verilog_ecdsa_driver_t * cons
 
 #endif
 
-static inline hal_error_t verilog_p256_point_pick_random(fp_int *k, ec_point_t *P)
-{
-#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
-
-  static const verilog_ecdsa_driver_t p256_driver = {
-      .name   = ECDSA256_NAME,
-      .bytes  = ECDSA256_OPERAND_BITS / 8,
-      .k_addr = ECDSA256_ADDR_K,
-      .x_addr = ECDSA256_ADDR_X,
-      .y_addr = ECDSA256_ADDR_Y
-  };
-
-  return verilog_point_pick_random(&p256_driver, k, P);
-
-#endif
-
-  return HAL_ERROR_CORE_NOT_FOUND;
-}
-
-static inline hal_error_t verilog_p384_point_pick_random(fp_int *k, ec_point_t *P)
-{
-#if HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
-
-  static const verilog_ecdsa_driver_t p384_driver = {
-    .name   = ECDSA384_NAME,
-    .bytes  = ECDSA384_OPERAND_BITS / 8,
-    .k_addr = ECDSA384_ADDR_K,
-    .x_addr = ECDSA384_ADDR_X,
-    .y_addr = ECDSA384_ADDR_Y
-  };
-
-  return verilog_point_pick_random(&p384_driver, k, P);
-
-#endif
-
-  return HAL_ERROR_CORE_NOT_FOUND;
-}
-
 /*
  * Pick a random point on the curve, return random scalar and
  * resulting point.
@@ -915,23 +877,39 @@ static hal_error_t point_pick_random(const ecdsa_curve_t * const curve,
 
   memset(k_buf, 0, sizeof(k_buf));
 
-#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER || HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
   switch (curve->curve) {
 
+#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
   case HAL_CURVE_P256:
-    if ((err = verilog_p256_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
+    static const verilog_ecdsa_driver_t p256_driver = {
+      .name   = ECDSA256_NAME,
+      .bytes  = ECDSA256_OPERAND_BITS / 8,
+      .k_addr = ECDSA256_ADDR_K,
+      .x_addr = ECDSA256_ADDR_X,
+      .y_addr = ECDSA256_ADDR_Y
+    };
+    if ((err = verilog_point_pick_random(&p256_driver, k, P)) != HAL_ERROR_CORE_NOT_FOUND)
       return err;
-  break;
+    break;
+#endif
 
+#if HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
   case HAL_CURVE_P384:
-    if ((err = verilog_p384_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
+    static const verilog_ecdsa_driver_t p384_driver = {
+      .name   = ECDSA384_NAME,
+      .bytes  = ECDSA384_OPERAND_BITS / 8,
+      .k_addr = ECDSA384_ADDR_K,
+      .x_addr = ECDSA384_ADDR_X,
+      .y_addr = ECDSA384_ADDR_Y
+    };
+    if ((err = verilog_point_pick_random(&p384_driver, k, P)) != HAL_ERROR_CORE_NOT_FOUND)
       return err;
-  break;
+    break;
+#endif
 
   default:
     break;
   }
-#endif
 
   /*
    * Calculate P = kG and return.
@@ -1287,7 +1265,11 @@ hal_error_t hal_ecdsa_key_from_ecpoint(hal_ecdsa_key_t **key_,
 }
 
 /*
- * Write private key in RFC 5915 ASN.1 DER format.
+ * Write private key in PKCS #8 PrivateKeyInfo DER format (RFC 5208).
+ * This is basically just the PKCS #8 wrapper around the ECPrivateKey
+ * format from RFC 5915, except that the OID naming the curve is in
+ * the privateKeyAlgorithm.parameters field in the PKCS #8 wrapper and
+ * is therefore omitted from the ECPrivateKey.
  *
  * This is hand-coded, and is approaching the limit where one should
  * probably be using an ASN.1 compiler like asn1c instead.
@@ -1314,27 +1296,29 @@ hal_error_t hal_ecdsa_private_key_to_der(const hal_ecdsa_key_t * const key,
 
   hal_error_t err;
 
-  size_t version_len, hlen, hlen_oct, hlen_oid, hlen_exp0, hlen_bit, hlen_exp1;
+  size_t version_len, hlen, hlen_oct, hlen_bit, hlen_exp1;
 
   if ((err = hal_asn1_encode_integer(version,                                    NULL, &version_len, 0)) != HAL_OK ||
       (err = hal_asn1_encode_header(ASN1_OCTET_STRING,          q_len,           NULL, &hlen_oct,    0)) != HAL_OK ||
-      (err = hal_asn1_encode_header(ASN1_OBJECT_IDENTIFIER,     curve->oid_len,  NULL, &hlen_oid,    0)) != HAL_OK ||
-      (err = hal_asn1_encode_header(ASN1_EXPLICIT_0, hlen_oid + curve->oid_len,  NULL, &hlen_exp0,   0)) != HAL_OK ||
       (err = hal_asn1_encode_header(ASN1_BIT_STRING,            (q_len + 1) * 2, NULL, &hlen_bit,    0)) != HAL_OK ||
       (err = hal_asn1_encode_header(ASN1_EXPLICIT_1, hlen_bit + (q_len + 1) * 2, NULL, &hlen_exp1,   0)) != HAL_OK)
     return err;
 
-  const size_t vlen = (version_len   +
-                       hlen_oct + q_len +
-                       hlen_oid + hlen_exp0 + curve->oid_len +
-                       hlen_bit + hlen_exp1 + (q_len + 1) * 2);
+  const size_t vlen = version_len + hlen_oct + q_len + hlen_exp1 + hlen_bit + (q_len + 1) * 2;
 
-  err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max);
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, NULL, &hlen, 0)) != HAL_OK)
+    return err;
 
-  if (der_len != NULL)
-    *der_len = hlen + vlen;
+  if ((err = hal_asn1_encode_pkcs8_privatekeyinfo(hal_asn1_oid_ecPublicKey, hal_asn1_oid_ecPublicKey_len,
+                                                  curve->oid, curve->oid_len,
+                                                  NULL, hlen + vlen,
+                                                  NULL, der_len, der_max)) != HAL_OK)
+    return err;
+                                                  
+  if (der == NULL)
+    return HAL_OK;
 
-  if (der == NULL || err != HAL_OK)
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max)) != HAL_OK)
     return err;
 
   uint8_t *d = der + hlen;
@@ -1350,15 +1334,6 @@ hal_error_t hal_ecdsa_private_key_to_der(const hal_ecdsa_key_t * const key,
   fp_to_unsigned_bin(unconst_fp_int(key->d), d + q_len - d_len);
   d += q_len;
 
-  if ((err = hal_asn1_encode_header(ASN1_EXPLICIT_0, hlen_oid + curve->oid_len, d, &hlen, der + der_max - d)) != HAL_OK)
-    return err;
-  d += hlen;
-  if ((err = hal_asn1_encode_header(ASN1_OBJECT_IDENTIFIER, curve->oid_len, d, &hlen, der + der_max - d)) != HAL_OK)
-    return err;
-  d += hlen;
-  memcpy(d, curve->oid, curve->oid_len);
-  d += curve->oid_len;
-
   if ((err = hal_asn1_encode_header(ASN1_EXPLICIT_1, hlen_bit + (q_len + 1) * 2, d, &hlen, der + der_max - d)) != HAL_OK)
     return err;
   d += hlen;
@@ -1372,9 +1347,10 @@ hal_error_t hal_ecdsa_private_key_to_der(const hal_ecdsa_key_t * const key,
   fp_to_unsigned_bin(unconst_fp_int(key->Q->y), d + q_len - Qy_len);
   d += q_len;
 
-  assert(d <= der + der_max);
-
-  return HAL_OK;
+  return hal_asn1_encode_pkcs8_privatekeyinfo(hal_asn1_oid_ecPublicKey, hal_asn1_oid_ecPublicKey_len,
+                                              curve->oid, curve->oid_len,
+                                              der, d - der,
+                                              der, der_len, der_max);
 }
 
 /*
@@ -1389,7 +1365,7 @@ size_t hal_ecdsa_private_key_to_der_len(const hal_ecdsa_key_t * const key)
 }
 
 /*
- * Read private key in RFC 5915 ASN.1 DER format.
+ * Read private key in PKCS #8 PrivateKeyInfo DER format (RFC 5208, RFC 5915).
  *
  * This is hand-coded, and is approaching the limit where one should
  * probably be using an ASN.1 compiler like asn1c instead.
@@ -1407,48 +1383,47 @@ hal_error_t hal_ecdsa_private_key_from_der(hal_ecdsa_key_t **key_,
   memset(keybuf, 0, keybuf_len);
   key->type = HAL_KEY_TYPE_EC_PRIVATE;
 
-  size_t hlen, vlen;
+  size_t hlen, vlen, alg_oid_len, curve_oid_len, privkey_len;
+  const uint8_t     *alg_oid,    *curve_oid,    *privkey;
   hal_error_t err;
 
-  if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, der, der_len, &hlen, &vlen)) != HAL_OK)
+  if ((err = hal_asn1_decode_pkcs8_privatekeyinfo(&alg_oid, &alg_oid_len,
+                                                  &curve_oid, &curve_oid_len,
+                                                  &privkey, &privkey_len,
+                                                  der, der_len)) != HAL_OK)
     return err;
 
-  const uint8_t * const der_end = der + hlen + vlen;
-  const uint8_t *d = der + hlen;
-  const ecdsa_curve_t *curve = NULL;
+  if (alg_oid_len != hal_asn1_oid_ecPublicKey_len ||
+      memcmp(alg_oid, hal_asn1_oid_ecPublicKey, alg_oid_len) != 0 ||
+      oid_to_curve(&key->curve, curve_oid, curve_oid_len) == NULL)
+    return HAL_ERROR_ASN1_PARSE_FAILED;
+
+  if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, privkey, privkey_len, &hlen, &vlen)) != HAL_OK)
+    return err;
+
+  const uint8_t * const der_end = privkey + hlen + vlen;
+  const uint8_t *d = privkey + hlen;
   fp_int version[1] = INIT_FP_INT;
 
   if ((err = hal_asn1_decode_integer(version, d, &hlen, vlen)) != HAL_OK)
-    goto fail;
+    return err;
   if (fp_cmp_d(version, 1) != FP_EQ)
-    lose(HAL_ERROR_ASN1_PARSE_FAILED);
+    return HAL_ERROR_ASN1_PARSE_FAILED;
   d += hlen;
 
   if ((err = hal_asn1_decode_header(ASN1_OCTET_STRING, d, der_end - d, &hlen, &vlen)) != HAL_OK)
-    return err;
+    goto fail;
   d += hlen;
   fp_read_unsigned_bin(key->d, unconst_uint8_t(d), vlen);
   d += vlen;
 
-  if ((err = hal_asn1_decode_header(ASN1_EXPLICIT_0, d, der_end - d, &hlen, &vlen)) != HAL_OK)
-    return err;
-  d += hlen;
-  if (vlen > der_end - d)
-    lose(HAL_ERROR_ASN1_PARSE_FAILED);
-  if ((err = hal_asn1_decode_header(ASN1_OBJECT_IDENTIFIER, d, vlen, &hlen, &vlen)) != HAL_OK)
-    return err;
-  d += hlen;
-  if ((curve = oid_to_curve(&key->curve, d, vlen)) == NULL)
-    lose(HAL_ERROR_ASN1_PARSE_FAILED);
-  d += vlen;
-
   if ((err = hal_asn1_decode_header(ASN1_EXPLICIT_1, d, der_end - d, &hlen, &vlen)) != HAL_OK)
-    return err;
+    goto fail;
   d += hlen;
   if (vlen > der_end - d)
     lose(HAL_ERROR_ASN1_PARSE_FAILED);
   if ((err = hal_asn1_decode_header(ASN1_BIT_STRING, d, vlen, &hlen, &vlen)) != HAL_OK)
-    return err;
+    goto fail;
   d += hlen;
   if (vlen < 4 || (vlen & 1) != 0 || *d++ != 0x00 || *d++ != 0x04)
     lose(HAL_ERROR_ASN1_PARSE_FAILED);
@@ -1474,8 +1449,6 @@ hal_error_t hal_ecdsa_private_key_from_der(hal_ecdsa_key_t **key_,
  * Write public key in SubjectPublicKeyInfo format, see RFCS 5280 and 5480.
  */
 
-static const uint8_t oid_ecPublicKey[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
-
 hal_error_t hal_ecdsa_public_key_to_der(const hal_ecdsa_key_t * const key,
                                         uint8_t *der, size_t *der_len, const size_t der_max)
 {
@@ -1508,7 +1481,7 @@ hal_error_t hal_ecdsa_public_key_to_der(const hal_ecdsa_key_t * const key,
     assert(d < der + der_max);
   }
 
-  return hal_asn1_encode_spki(oid_ecPublicKey, sizeof(oid_ecPublicKey),
+  return hal_asn1_encode_spki(hal_asn1_oid_ecPublicKey, hal_asn1_oid_ecPublicKey_len,
                               curve->oid, curve->oid_len,
                               der, ecpoint_len,
                               der, der_len, der_max);
@@ -1551,7 +1524,8 @@ hal_error_t hal_ecdsa_public_key_from_der(hal_ecdsa_key_t **key_,
     return err;
 
   if (alg_oid == NULL || curve_oid == NULL || pubkey == NULL ||
-      alg_oid_len != sizeof(oid_ecPublicKey) || memcmp(alg_oid, oid_ecPublicKey, alg_oid_len) != 0 ||
+      alg_oid_len != hal_asn1_oid_ecPublicKey_len ||
+      memcmp(alg_oid, hal_asn1_oid_ecPublicKey, alg_oid_len) != 0 ||
       (curve = oid_to_curve(&key->curve, curve_oid, curve_oid_len)) == NULL ||
       pubkey_len < 3 || (pubkey_len & 1) == 0 || pubkey[0] != 0x04 ||
       pubkey_len / 2 != fp_unsigned_bin_size(unconst_fp_int(curve->q)))
diff --git a/rsa.c b/rsa.c
index e24b5eb..3cea42c 100644
--- a/rsa.c
+++ b/rsa.c
@@ -673,7 +673,7 @@ hal_error_t hal_rsa_key_gen(const hal_core_t *core,
 
 /*
  * Just enough ASN.1 to read and write PKCS #1.5 RSAPrivateKey syntax
- * (RFC 2313 section 7.2).
+ * (RFC 2313 section 7.2) wrapped in a PKCS #8 PrivateKeyInfo (RFC 5208).
  *
  * RSAPrivateKey fields in the required order.
  */
@@ -709,15 +709,12 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
   RSAPrivateKey_fields;
 #undef _
 
-  /*
-   * Encode header.
-   */
-
-  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max))  != HAL_OK)
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, NULL, &hlen, 0)) != HAL_OK)
     return err;
 
-  if (der_len != NULL)
-    *der_len = hlen + vlen;
+  if ((err = hal_asn1_encode_pkcs8_privatekeyinfo(hal_asn1_oid_rsaEncryption, hal_asn1_oid_rsaEncryption_len,
+                                                  NULL, 0, NULL, hlen + vlen, NULL, der_len, der_max)) != HAL_OK)
+    return err;
 
   if (der == NULL)
     return HAL_OK;
@@ -726,13 +723,18 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
    * Encode data.
    */
 
-  der += hlen;
+  if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max)) != HAL_OK)
+    return err;
 
-#define _(x) { size_t n; if ((err = hal_asn1_encode_integer(x, der, &n, vlen)) != HAL_OK) return err; der += n; vlen -= n; }
+  uint8_t *d = der + hlen;
+  memset(d, 0, vlen);
+
+#define _(x) { size_t n; if ((err = hal_asn1_encode_integer(x, d, &n, vlen)) != HAL_OK) return err; d += n; vlen -= n; }
   RSAPrivateKey_fields;
 #undef _
 
-  return HAL_OK;
+  return hal_asn1_encode_pkcs8_privatekeyinfo(hal_asn1_oid_rsaEncryption, hal_asn1_oid_rsaEncryption_len,
+                                              NULL, 0, der, d - der, der, der_len, der_max);
 }
 
 size_t hal_rsa_private_key_to_der_len(const hal_rsa_key_t * const key)
@@ -754,21 +756,33 @@ hal_error_t hal_rsa_private_key_from_der(hal_rsa_key_t **key_,
 
   key->type = HAL_KEY_TYPE_RSA_PRIVATE;
 
-  hal_error_t err = HAL_OK;
-  size_t hlen, vlen;
+  size_t hlen, vlen, alg_oid_len, curve_oid_len, privkey_len;
+  const uint8_t     *alg_oid,    *curve_oid,    *privkey;
+  hal_error_t err;
 
-  if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, der, der_len, &hlen, &vlen)) != HAL_OK)
+  if ((err = hal_asn1_decode_pkcs8_privatekeyinfo(&alg_oid, &alg_oid_len,
+                                                  &curve_oid, &curve_oid_len,
+                                                  &privkey, &privkey_len,
+                                                  der, der_len)) != HAL_OK)
     return err;
 
-  der += hlen;
+  if (alg_oid_len != hal_asn1_oid_rsaEncryption_len ||
+      memcmp(alg_oid, hal_asn1_oid_rsaEncryption, alg_oid_len) != 0 ||
+      curve_oid_len != 0)
+    return HAL_ERROR_ASN1_PARSE_FAILED;
+
+  if ((err = hal_asn1_decode_header(ASN1_SEQUENCE, privkey, privkey_len, &hlen, &vlen)) != HAL_OK)
+    return err;
+
+  const uint8_t *d = privkey + hlen;
 
   fp_int version[1] = INIT_FP_INT;
 
-#define _(x) { size_t i; if ((err = hal_asn1_decode_integer(x, der, &i, vlen)) != HAL_OK) return err; der += i; vlen -= i; }
+#define _(x) { size_t n; if ((err = hal_asn1_decode_integer(x, d, &n, vlen)) != HAL_OK) return err; d += n; vlen -= n; }
   RSAPrivateKey_fields;
 #undef _
 
-  if (fp_cmp_d(version, 0) != FP_EQ)
+  if (d != privkey + privkey_len || !fp_iszero(version))
     return HAL_ERROR_ASN1_PARSE_FAILED;
 
   *key_ = key;
@@ -780,8 +794,6 @@ hal_error_t hal_rsa_private_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)
 {
@@ -810,7 +822,7 @@ hal_error_t hal_rsa_public_key_to_der(const hal_rsa_key_t * const key,
       return err;
   }
 
-  return hal_asn1_encode_spki(oid_rsaEncryption, sizeof(oid_rsaEncryption),
+  return hal_asn1_encode_spki(hal_asn1_oid_rsaEncryption, hal_asn1_oid_rsaEncryption_len,
                               NULL, 0, der, hlen + vlen,
                               der, der_len, der_max);
 
@@ -843,7 +855,7 @@ hal_error_t hal_rsa_public_key_from_der(hal_rsa_key_t **key_,
     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)
+      alg_oid_len != hal_asn1_oid_rsaEncryption_len || memcmp(alg_oid, hal_asn1_oid_rsaEncryption, alg_oid_len) != 0)
     return HAL_ERROR_ASN1_PARSE_FAILED;
 
   size_t len, hlen, vlen;



More information about the Commits mailing list