[Cryptech-Commits] [sw/libhal] 02/02: First round of debugging based on RPC pkey tests: mostly ASN.1 silliness, with a bit of PKCS #1.5 padding silliness for desert.

git at cryptech.is git at cryptech.is
Sat Mar 12 00:35:53 UTC 2016


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

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

commit 7e4d5d73cf1fdcbee10a06a307529955ad17919e
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Fri Mar 11 19:24:00 2016 -0500

    First round of debugging based on RPC pkey tests: mostly ASN.1
    silliness, with a bit of PKCS #1.5 padding silliness for desert.
---
 asn1.c                |  3 ++-
 ks.c                  |  1 +
 ks_mmap.c             |  1 +
 ks_volatile.c         |  1 +
 rpc_pkey.c            | 36 +++++++++++++++++++++++++++++-------
 tests/test-rpc_pkey.c | 22 +++++++++++++++-------
 6 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/asn1.c b/asn1.c
index c50a7b4..2206ec3 100644
--- a/asn1.c
+++ b/asn1.c
@@ -161,7 +161,8 @@ hal_error_t hal_asn1_encode_spki(const uint8_t * const alg_oid,   const size_t a
                                  const uint8_t * const pubkey,    const size_t pubkey_len,
                                  uint8_t *der, size_t *der_len, const size_t der_max)
 {
-  if (alg_oid == NULL || alg_oid_len == 0 || pubkey == NULL || pubkey_len == 0 || (curve_oid == NULL && curve_oid_len != 0))
+  if (alg_oid == NULL || alg_oid_len == 0 || pubkey_len == 0 ||
+      (der != NULL && pubkey == NULL) || (curve_oid == NULL && curve_oid_len != 0))
     return HAL_ERROR_BAD_ARGUMENTS;
 
   const uint8_t curve_oid_tag = curve_oid == NULL ? ASN1_NULL : ASN1_OBJECT_IDENTIFIER;
diff --git a/ks.c b/ks.c
index a856bbf..d1ce089 100644
--- a/ks.c
+++ b/ks.c
@@ -93,6 +93,7 @@ hal_error_t hal_ks_store(const hal_key_type_t type,
 
   hal_ks_key_t k;
   memset(&k, 0, sizeof(k));
+  k.der_len = sizeof(k.der);
 
   uint8_t kek[KEK_LENGTH];
   size_t kek_len;
diff --git a/ks_mmap.c b/ks_mmap.c
index 4c752ea..5eb2a13 100644
--- a/ks_mmap.c
+++ b/ks_mmap.c
@@ -168,6 +168,7 @@ hal_error_t hal_ks_get_kek(uint8_t *kek,
     return err;
 
   memcpy(kek, kekbuf, len);
+  *kek_len = len;
   return HAL_OK;
 }
 
diff --git a/ks_volatile.c b/ks_volatile.c
index b71e27e..9a47d52 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -132,6 +132,7 @@ hal_error_t hal_ks_get_kek(uint8_t *kek,
     return err;
 
   memcpy(kek, kekbuf, len);
+  *kek_len = len;
   return HAL_OK;
 }
 
diff --git a/rpc_pkey.c b/rpc_pkey.c
index e7331ab..96680ed 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -669,13 +669,13 @@ static hal_error_t sign(const hal_session_handle_t session,
 }
 
 /*
- * Verify something using private key associated with handle.
+ * Verify something using public key associated with handle.
  *
  * RSA has enough quirks that it's simplest to split this out into
  * algorithm-specific functions.
  */
 
-static hal_error_t verify_rsa(uint8_t *keybuf, const size_t keybuf_len,
+static hal_error_t verify_rsa(uint8_t *keybuf, const size_t keybuf_len, const hal_key_type_t type,
                               const uint8_t * const der, const size_t der_len,
                               const hal_hash_handle_t hash,
                               const uint8_t * input, size_t input_len,
@@ -688,7 +688,18 @@ static hal_error_t verify_rsa(uint8_t *keybuf, const size_t keybuf_len,
   assert(signature != NULL && signature_len > 0);
   assert((hash.handle == hal_hash_handle_none.handle) != (input == NULL || input_len == 0));
 
-  if ((err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
+  switch (type) {
+  case HAL_KEY_TYPE_RSA_PRIVATE:
+    err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len);
+    break;
+  case HAL_KEY_TYPE_RSA_PUBLIC:
+    err = hal_rsa_public_key_from_der(&key, keybuf, keybuf_len, der, der_len);
+    break;
+  default:
+    err = HAL_ERROR_IMPOSSIBLE;
+  }
+
+  if (err != HAL_OK)
     return err;
 
   if (input == NULL) {
@@ -711,7 +722,7 @@ static hal_error_t verify_rsa(uint8_t *keybuf, const size_t keybuf_len,
   return HAL_OK;
 }
 
-static hal_error_t verify_ecdsa(uint8_t *keybuf, const size_t keybuf_len,
+static hal_error_t verify_ecdsa(uint8_t *keybuf, const size_t keybuf_len, const hal_key_type_t type,
                                 const uint8_t * const der, const size_t der_len,
                                 const hal_hash_handle_t hash,
                                 const uint8_t * input, size_t input_len,
@@ -724,7 +735,18 @@ static hal_error_t verify_ecdsa(uint8_t *keybuf, const size_t keybuf_len,
   assert(signature != NULL && signature_len > 0);
   assert((hash.handle == hal_hash_handle_none.handle) != (input == NULL || input_len == 0));
 
-  if ((err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
+  switch (type) {
+  case HAL_KEY_TYPE_EC_PRIVATE:
+    err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len);
+    break;
+  case HAL_KEY_TYPE_EC_PUBLIC:
+    err = hal_ecdsa_public_key_from_der(&key, keybuf, keybuf_len, der, der_len);
+    break;
+  default:
+    err = HAL_ERROR_IMPOSSIBLE;
+  }
+
+  if (err != HAL_OK)
     return err;
 
   if (input == NULL) {
@@ -755,7 +777,7 @@ static hal_error_t verify(const hal_session_handle_t session,
   if (slot == NULL)
     return HAL_ERROR_KEY_NOT_FOUND;
 
-  hal_error_t (*verifier)(uint8_t *keybuf, const size_t keybuf_len,
+  hal_error_t (*verifier)(uint8_t *keybuf, const size_t keybuf_len, const hal_key_type_t type,
                           const uint8_t * const der, const size_t der_len,
                           const hal_hash_handle_t hash,
                           const uint8_t * const input,  const size_t input_len,
@@ -782,7 +804,7 @@ static hal_error_t verify(const hal_session_handle_t session,
   err = hal_ks_fetch(slot->type, slot->name, slot->name_len, NULL, NULL, der, &der_len, sizeof(der), &slot->ks_hint);
 
   if (err == HAL_OK)
-    err = verifier(keybuf, sizeof(keybuf), der, der_len, hash, input, input_len, signature, signature_len);
+    err = verifier(keybuf, sizeof(keybuf), slot->type, der, der_len, hash, input, input_len, signature, signature_len);
 
   memset(keybuf, 0, sizeof(keybuf));
   memset(der,    0, sizeof(der));
diff --git a/tests/test-rpc_pkey.c b/tests/test-rpc_pkey.c
index 4fdead9..6506ea6 100644
--- a/tests/test-rpc_pkey.c
+++ b/tests/test-rpc_pkey.c
@@ -74,7 +74,7 @@ static int test_rsa_testvec(const rsa_tc_t * const tc)
                                       tc->dQ.val, tc->dQ.len)) != HAL_OK)
     return printf("Could not load RSA private key from test vector: %s\n", hal_error_string(err)), 0;
 
-  const uint8_t private_label[] = "private key", public_label[] = "private key";
+  const uint8_t private_label[] = "RSA private key", public_label[] = "RSA public key";
 
   uint8_t private_der[hal_rsa_private_key_to_der_len(tc_key)];
   uint8_t public_der[hal_rsa_public_key_to_der_len(tc_key)];
@@ -99,17 +99,25 @@ static int test_rsa_testvec(const rsa_tc_t * const tc)
                                HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK)
     return printf("Could not load public key into RPC: %s\n", hal_error_string(err)), 0;
 
-  uint8_t m_buf[tc->m.len], s_buf[tc->s.len];
+  uint8_t sig[tc->s.len];
 
-  if ((err = hal_rpc_pkey_sign(session, private_key, hal_hash_handle_none, tc->m.val, tc->m.len,
-                               s_buf, &len, sizeof(s_buf))) != HAL_OK)
+  /*
+   * Raw RSA test cases include PKCS #1.5 padding, we need to drill down to the DigestInfo.
+   */
+  assert(tc->m.len > 4 && tc->m.val[0] == 0x00 && tc->m.val[1] == 0x01 && tc->m.val[2] == 0xff);
+  const uint8_t *digestinfo = memchr(tc->m.val + 2, 0x00, tc->m.len - 2);
+  assert(digestinfo != NULL);
+  const size_t digestinfo_len = tc->m.val + tc->m.len - ++digestinfo;
+
+  if ((err = hal_rpc_pkey_sign(session, private_key, hal_hash_handle_none,
+                               digestinfo, digestinfo_len, sig, &len, sizeof(sig))) != HAL_OK)
     return printf("Could not sign: %s\n", hal_error_string(err)), 0;
 
-  if (tc->s.len != len || memcmp(s_buf, tc->s.val, tc->s.len) != 0)
+  if (tc->s.len != len || memcmp(sig, tc->s.val, tc->s.len) != 0)
     return printf("MISMATCH\n"), 0;
 
-  if ((err = hal_rpc_pkey_verify(session, public_key, hal_hash_handle_none, tc->s.val, tc->s.len,
-                                 m_buf, sizeof(m_buf))) != HAL_OK)
+  if ((err = hal_rpc_pkey_verify(session, public_key, hal_hash_handle_none,
+                                 digestinfo, digestinfo_len, tc->s.val, tc->s.len)) != HAL_OK)
     return printf("Could not verify: %s\n", hal_error_string(err)), 0;
 
   if ((err = hal_rpc_pkey_delete(private_key)) != HAL_OK)



More information about the Commits mailing list