[CICN-26] Add support for HMAC 80/23980/1
authorOlivier Roques <[email protected]>
Thu, 12 Dec 2019 11:40:49 +0000 (12:40 +0100)
committerOlivier Roques <[email protected]>
Fri, 13 Dec 2019 11:00:10 +0000 (12:00 +0100)
Add support for HMAC, a symmetric signature algorithm, and
fix various bugs.

Signed-off-by: Olivier Roques <[email protected]>
Change-Id: Ic73e1f68813500fb37a8da4286424875438040f3

libparc/parc/security/parc_InMemoryVerifier.c
libparc/parc/security/parc_SymmetricKeySigner.c

index 8955e1f..00dddf4 100644 (file)
@@ -51,6 +51,8 @@ _parcInMemoryVerifier_Destructor(PARCInMemoryVerifier **verifierPtr)
     parcCryptoHasher_Release(&(verifier->hasher_sha256));
     parcCryptoHasher_Release(&(verifier->hasher_sha512));
     parcCryptoCache_Destroy(&(verifier->key_cache));
+    parcMemory_Deallocate((void **)verifierPtr);
+    *verifierPtr = NULL;
 
     return true;
 }
@@ -88,8 +90,6 @@ _parcInMemoryVerifier_GetCryptoHasher(void *interfaceContext, PARCKeyId *keyid,
         return false;
     }
 
-    parcAssertFalse(parcKey_GetSigningAlgorithm(key) == PARCSigningAlgorithm_HMAC, "HMAC not supported yet");
-
     switch (hashType) {
         case PARCCryptoHashType_SHA256:
             return verifier->hasher_sha256;
@@ -137,15 +137,14 @@ _parcInMemoryVerifier_AllowedCryptoSuite(void *interfaceContext, PARCKeyId *keyi
             }
             break;
 
-            
-        case PARCSigningAlgorithm_DSA:
+      case PARCSigningAlgorithm_DSA:
             switch (suite) {
                 default:
                     return false;
             }
             break;
 
-        case PARCSigningAlgorithm_HMAC:
+      case PARCSigningAlgorithm_HMAC:
             switch (suite) {
                 case PARCCryptoSuite_HMAC_SHA256:
                     return true;
@@ -154,7 +153,7 @@ _parcInMemoryVerifier_AllowedCryptoSuite(void *interfaceContext, PARCKeyId *keyi
             }
             break;
 
-        default:
+      default:
             parcTrapUnexpectedState("Unknown signing algorithm: %s",
                                 parcSigningAlgorithm_ToString(parcKey_GetSigningAlgorithm(key)));
             return false;
@@ -167,7 +166,9 @@ static bool _parcInMemoryVerifier_RSAKey_Verify(PARCInMemoryVerifier *verifier,
                                                 PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey);
 
 static bool _parcInMemoryVerifier_ECDSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHash *localHash,
-                                      PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey);
+                                                  PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey);
+
+static bool _parcInMemoryVerifier_HMACKey_Verify(PARCCryptoHash *localHash, PARCSignature *signatureToVerify);
 /**
  * The signature verifies if:
  * 0) we know the key for keyid
@@ -214,14 +215,13 @@ _parcInMemoryVerifier_VerifyDigest(void *interfaceContext, PARCKeyId *keyid, PAR
         case PARCSigningAlgorithm_ECDSA:
             return _parcInMemoryVerifier_ECDSAKey_Verify(verifier, locallyComputedHash, objectSignature, parcKey_GetKey(key));
 
+        case PARCSigningAlgorithm_HMAC:
+            return _parcInMemoryVerifier_HMACKey_Verify(locallyComputedHash, objectSignature);
+
         case PARCSigningAlgorithm_DSA:
             parcTrapNotImplemented("DSA not supported");
             break;
 
-        case PARCSigningAlgorithm_HMAC:
-            parcTrapNotImplemented("HMAC not supported");
-            break;
-
         default:
             parcTrapUnexpectedState("Unknown signing algorithm: %d", parcSignature_GetSigningAlgorithm(objectSignature));
     }
@@ -334,7 +334,7 @@ _parcInMemoryVerifier_RSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHa
  */
 static bool
 _parcInMemoryVerifier_ECDSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHash *localHash,
-                                    PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey)
+                                      PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey)
 {
     const uint8_t *der_bytes = parcByteArray_Array(parcBuffer_Array(derEncodedKey));
 
@@ -383,6 +383,23 @@ _parcInMemoryVerifier_ECDSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCrypto
     return false;
 }
 
+/**
+ * Return if the signature verify with the local hash.
+ *
+ * PRECONDITION:
+ *  - You know the signature is HMAC.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static bool
+_parcInMemoryVerifier_HMACKey_Verify(PARCCryptoHash *localHash, PARCSignature *signatureToVerify)
+{
+  return parcBuffer_Equals(parcCryptoHash_GetDigest(localHash), parcSignature_GetSignature(signatureToVerify));
+}
+
 PARCVerifierInterface *PARCInMemoryVerifierAsVerifier = &(PARCVerifierInterface) {
     .GetCryptoHasher = _parcInMemoryVerifier_GetCryptoHasher,
     .VerifyDigest = _parcInMemoryVerifier_VerifyDigest,
index 5c2db77..8825696 100644 (file)
@@ -85,15 +85,13 @@ static int
 _hmacInit(void *ctx)
 {
     // reset the HMAC state with NULLs, so we'll re-use the values we had from setup.
-    HMAC_Init_ex((HMAC_CTX *) ctx, NULL, 0, NULL, NULL);
-    return 0;
+    return HMAC_Init_ex((HMAC_CTX *) ctx, NULL, 0, NULL, NULL);
 }
 
 static int
 _hmacUpdate(void *ctx, const void *buffer, size_t length)
 {
-    HMAC_Update(ctx, buffer, length);
-    return 0;
+    return HMAC_Update(ctx, buffer, length);
 }
 
 static PARCBuffer*
@@ -244,12 +242,7 @@ static size_t
 _GetSignatureSize(PARCSymmetricKeySigner *signer)
 {
   parcAssertNotNull(signer, "Parameter must be non-null CCNxFileKeystore");
-
-  // TODO: what is the best way to expose this?
-  PARCSymmetricKeyStore *keyStore = signer->keyStore;
-  PARCBuffer *secretKeyBuffer = parcSymmetricKeyStore_GetKey(keyStore);
-
-  return parcBuffer_Limit(secretKeyBuffer);
+  return (size_t)(signer->hashLength);
 }
 
 // ==================================================
@@ -266,7 +259,8 @@ _signDigestNoAlloc(PARCSymmetricKeySigner *interfaceContext, const PARCCryptoHas
     // The digest computed via our hash function (hmac) is the actual signature.
     // just need to wrap it up with the right parameters.
     PARCBuffer *signatureBits = parcBuffer_Wrap(signature, sig_len, 0, sig_len);
-    PARCSignature  *result = parcSignature_Create(_getSigningAlgorithm(interfaceContext), parcCryptoHash_GetDigestType(hashToSign), signatureBits);
+    parcBuffer_PutBuffer(signatureBits, parcCryptoHash_GetDigest(hashToSign));
+    PARCSignature *result = parcSignature_Create(_getSigningAlgorithm(interfaceContext), parcCryptoHash_GetDigestType(hashToSign), signatureBits);
     parcBuffer_Release(&signatureBits);
     return result;
 }