1// 2// CommonHMac.c 3// CommonCrypto 4// 5// Created by Richard Murphy on 1/21/14. 6// Copyright (c) 2014 Apple Inc. All rights reserved. 7// 8 9#include <stdio.h> 10#include "testbyteBuffer.h" 11#include "capabilities.h" 12#include "testmore.h" 13#include "testutil.h" 14#include <string.h> 15 16#include <CommonCrypto/CommonCryptor.h> 17#include <CommonCrypto/CommonDigest.h> 18#include <CommonCrypto/CommonHMAC.h> 19#include <CommonCrypto/CommonHMacSPI.h> 20#include <CommonCrypto/CommonKeyDerivationSPI.h> 21#include <CommonCrypto/CommonDigestSPI.h> 22 23 24typedef struct HMacVector_t { 25 char *keystr; 26 char *input; 27 char *md5str; 28 char *sha1str; 29 char *sha224str; 30 char *sha256str; 31 char *sha384str; 32 char *sha512str; 33} HMacVector; 34 35static HMacVector hmv[] = { 36 { // Test Case 1 http://www.faqs.org/rfcs/rfc4231.html MD5 derived 37 "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", 38 "Hi There", 39 "5ccec34ea9656392457fa1ac27f08fbc", 40 "b617318655057264e28bc0b6fb378c8ef146be00", 41 "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22", 42 "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7", 43 "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6", 44 "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854", 45 }, 46 { // Test Vector from http://www.faqs.org/rfcs/rfc2104.html - all but MD5 derived 47 "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", 48 "Hi There", 49 "9294727a3638bb1c13f48ef8158bfc9d", 50 "675b0b3a1b4ddf4e124872da6c2f632bfed957e9", 51 "4e841ce7a4ae83fbcf71e3cd64bfbf277f73a14680aae8c518ac7861", 52 "492ce020fe2534a5789dc3848806c78f4f6711397f08e7e7a12ca5a4483c8aa6", 53 "7afaa633e20d379b02395915fbc385ff8dc27dcd3885e1068ab942eeab52ec1f20ad382a92370d8b2e0ac8b83c4d53bf", 54 "7641c48a3b4aa8f887c07b3e83f96affb89c978fed8c96fcbbf4ad596eebfe496f9f16da6cd080ba393c6f365ad72b50d15c71bfb1d6b81f66a911786c6ce932", 55 }, 56 { // Try this with a NULL key 57 NULL, 58 "Hi There", 59 "72c33c78cac0b7a581ac263a344ed01d", 60 "69536cc84eee5fe51c5b051aff8485f5c9ef0b58", 61 "da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945", 62 "e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b", 63 "da5393cef424a670d6db42c6ed6e7920779dfa4cbb98bf1c2e9c12ae10d10905d0c9e9d576c2a613be54b8daea246d4b", 64 "f7688a104326d36c1940f6d28d746c0661d383e0d14fe8a04649444777610f5dd9565a36846ab9e9e734cf380d3a070d8ef021b5f3a50c481710a464968e3419", 65 }, 66 { // Same with a "" Key - Zero Length with string 67 "", 68 "Hi There", 69 "72c33c78cac0b7a581ac263a344ed01d", 70 "69536cc84eee5fe51c5b051aff8485f5c9ef0b58", 71 "da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945", 72 "e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b", 73 "da5393cef424a670d6db42c6ed6e7920779dfa4cbb98bf1c2e9c12ae10d10905d0c9e9d576c2a613be54b8daea246d4b", 74 "f7688a104326d36c1940f6d28d746c0661d383e0d14fe8a04649444777610f5dd9565a36846ab9e9e734cf380d3a070d8ef021b5f3a50c481710a464968e3419", 75 }, 76 77}; 78 79static size_t hmvLen = sizeof(hmv) / sizeof(HMacVector); 80 81 82 83static char * testString(char *format, CCDigestAlgorithm alg) { 84 static char thestring[80]; 85 sprintf(thestring, format, digestName(alg)); 86 return thestring; 87} 88 89static int testOriginalOneShotHMac(CCDigestAlgorithm alg, byteBuffer key, char *input, byteBuffer expected) { 90 CCHmacAlgorithm hmacAlg = digestID2HMacID(alg); 91 byteBuffer computedMD = mallocDigestByteBuffer(alg); 92 int status = 0; 93 94 CCHmac(hmacAlg, key->bytes, key->len, input, strlen(input), computedMD->bytes); 95 ok(status = expectedEqualsComputed(testString("Original OneShot HMac-%s", alg), expected, computedMD), "HMac is as expected"); 96 free(computedMD); 97 return status; 98} 99 100static int testOriginalDiscreetHMac(CCDigestAlgorithm alg, byteBuffer key, char *input, byteBuffer expected) { 101 CCHmacAlgorithm hmacAlg = digestID2HMacID(alg); 102 byteBuffer computedMD = mallocDigestByteBuffer(alg); 103 CCHmacContext ctx; 104 int status = 0; 105 106 CCHmacInit(&ctx, hmacAlg, key->bytes, key->len); 107 CCHmacUpdate(&ctx, input, strlen(input)); 108 CCHmacFinal(&ctx, computedMD->bytes); 109 ok(status = expectedEqualsComputed(testString("Original Discreet HMac-%s", alg), expected, computedMD), "HMac is as expected"); 110 free(computedMD); 111 return status; 112} 113 114static int testNewOneShotHMac(CCDigestAlgorithm alg, byteBuffer key, char *input, byteBuffer expected) { 115 byteBuffer computedMD = mallocDigestByteBuffer(alg); 116 int status = 0; 117 118 CCHmacOneShot(alg, key->bytes, key->len, input, strlen(input), computedMD->bytes); 119 ok(status = expectedEqualsComputed(testString("New OneShot HMac-%s", alg), expected, computedMD), "HMac is as expected"); 120 free(computedMD); 121 return status; 122} 123 124static int testNewDiscreetHMac(CCDigestAlgorithm alg, byteBuffer key, char *input, byteBuffer expected) { 125 byteBuffer computedMD = mallocDigestByteBuffer(alg); 126 byteBuffer computedMD2 = mallocDigestByteBuffer(alg); 127 int status = 0; 128 129 CCHmacContextRef ctx = CCHmacCreate(alg, key->bytes, key->len); 130 CCHmacContextRef ctx2 = CCHmacClone(ctx); 131 CCHmacUpdate(ctx, input, strlen(input)); 132 CCHmacFinal(ctx, computedMD->bytes); 133 CCHmacDestroy(ctx); 134 CCHmacUpdate(ctx2, input, strlen(input)); 135 CCHmacFinal(ctx2, computedMD2->bytes); 136 CCHmacDestroy(ctx2); 137 ok(status = expectedEqualsComputed(testString("New OneShot HMac-%s", alg), expected, computedMD), "HMac is as expected"); 138 ok(status = expectedEqualsComputed(testString("New OneShot HMac-%s", alg), expected, computedMD2), "HMac is as expected"); 139 free(computedMD); 140 free(computedMD2); 141 return status; 142} 143 144static int testAllHMacs(CCDigestAlgorithm alg, byteBuffer key, char *input, byteBuffer expected) { 145 int status = 0; 146 147 ok(status = testOriginalOneShotHMac(alg, key, input, expected), "Test Original One Shot version of HMac"); 148 ok(status &= testOriginalDiscreetHMac(alg, key, input, expected), "Test Original Discreet version of HMac"); 149 ok(status &= testNewOneShotHMac(alg, key, input, expected), "Test New One Shot version of HMac"); 150 ok(status &= testNewDiscreetHMac(alg, key, input, expected), "Test New Discreet version of HMac"); 151 return status; 152} 153 154static int testHMac(HMacVector *hv) { 155 byteBuffer key = hexStringToBytes(hv->keystr); 156 int status = 0; 157 158 byteBuffer expectedMD = hexStringToBytesIfNotNULL(hv->md5str); 159 ok(status = testAllHMacs(kCCDigestMD5, key, hv->input, expectedMD), "Testing all MD5 Implementations"); 160 free(expectedMD); 161 162 expectedMD = hexStringToBytesIfNotNULL(hv->sha1str); 163 ok(status &= testAllHMacs(kCCDigestSHA1, key, hv->input, expectedMD), "Testing all SHA1 Implementations"); 164 free(expectedMD); 165 166 expectedMD = hexStringToBytesIfNotNULL(hv->sha224str); 167 ok(status &= testAllHMacs(kCCDigestSHA224, key, hv->input, expectedMD), "Testing all SHA224 Implementations"); 168 free(expectedMD); 169 170 expectedMD = hexStringToBytesIfNotNULL(hv->sha256str); 171 ok(status &= testAllHMacs(kCCDigestSHA256, key, hv->input, expectedMD), "Testing all SHA256 Implementations"); 172 free(expectedMD); 173 174 expectedMD = hexStringToBytesIfNotNULL(hv->sha384str); 175 ok(status &= testAllHMacs(kCCDigestSHA384, key, hv->input, expectedMD), "Testing all SHA384 Implementations"); 176 free(expectedMD); 177 178 expectedMD = hexStringToBytesIfNotNULL(hv->sha512str); 179 ok(status &= testAllHMacs(kCCDigestSHA512, key, hv->input, expectedMD), "Testing all SHA512 Implementations"); 180 free(expectedMD); 181 182 return status; 183} 184 185static size_t testsPerVector = 3; 186 187int CommonHMac(int argc, char *const *argv) { 188 plan_tests((int) (hmvLen*testsPerVector)); 189 190 for(size_t testcase = 0; testcase < hmvLen; testcase++) { 191 // diag("Test %lu\n", testcase + 1); 192 ok(testHMac(&hmv[testcase]), "Successful full test of HMAC Vector"); 193 } 194 return 0; 195} 196 197