1*da668aa1SThomas Huth /* 2*da668aa1SThomas Huth * QEMU Crypto hmac algorithms tests 3*da668aa1SThomas Huth * 4*da668aa1SThomas Huth * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. 5*da668aa1SThomas Huth * 6*da668aa1SThomas Huth * Authors: 7*da668aa1SThomas Huth * Longpeng(Mike) <longpeng2@huawei.com> 8*da668aa1SThomas Huth * 9*da668aa1SThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or 10*da668aa1SThomas Huth * (at your option) any later version. See the COPYING file in the 11*da668aa1SThomas Huth * top-level directory. 12*da668aa1SThomas Huth * 13*da668aa1SThomas Huth */ 14*da668aa1SThomas Huth 15*da668aa1SThomas Huth #include "qemu/osdep.h" 16*da668aa1SThomas Huth #include "crypto/init.h" 17*da668aa1SThomas Huth #include "crypto/hmac.h" 18*da668aa1SThomas Huth 19*da668aa1SThomas Huth #define INPUT_TEXT1 "ABCDEFGHIJKLMNOPQRSTUVWXY" 20*da668aa1SThomas Huth #define INPUT_TEXT2 "Zabcdefghijklmnopqrstuvwx" 21*da668aa1SThomas Huth #define INPUT_TEXT3 "yz0123456789" 22*da668aa1SThomas Huth #define INPUT_TEXT INPUT_TEXT1 \ 23*da668aa1SThomas Huth INPUT_TEXT2 \ 24*da668aa1SThomas Huth INPUT_TEXT3 25*da668aa1SThomas Huth 26*da668aa1SThomas Huth #define KEY "monkey monkey monkey monkey" 27*da668aa1SThomas Huth 28*da668aa1SThomas Huth typedef struct QCryptoHmacTestData QCryptoHmacTestData; 29*da668aa1SThomas Huth struct QCryptoHmacTestData { 30*da668aa1SThomas Huth QCryptoHashAlgorithm alg; 31*da668aa1SThomas Huth const char *hex_digest; 32*da668aa1SThomas Huth }; 33*da668aa1SThomas Huth 34*da668aa1SThomas Huth static QCryptoHmacTestData test_data[] = { 35*da668aa1SThomas Huth { 36*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_MD5, 37*da668aa1SThomas Huth .hex_digest = 38*da668aa1SThomas Huth "ede9cb83679ba82d88fbeae865b3f8fc", 39*da668aa1SThomas Huth }, 40*da668aa1SThomas Huth { 41*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_SHA1, 42*da668aa1SThomas Huth .hex_digest = 43*da668aa1SThomas Huth "c7b5a631e3aac975c4ededfcd346e469" 44*da668aa1SThomas Huth "dbc5f2d1", 45*da668aa1SThomas Huth }, 46*da668aa1SThomas Huth { 47*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_SHA224, 48*da668aa1SThomas Huth .hex_digest = 49*da668aa1SThomas Huth "5f768179dbb29ca722875d0f461a2e2f" 50*da668aa1SThomas Huth "597d0210340a84df1a8e9c63", 51*da668aa1SThomas Huth }, 52*da668aa1SThomas Huth { 53*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_SHA256, 54*da668aa1SThomas Huth .hex_digest = 55*da668aa1SThomas Huth "3798f363c57afa6edaffe39016ca7bad" 56*da668aa1SThomas Huth "efd1e670afb0e3987194307dec3197db", 57*da668aa1SThomas Huth }, 58*da668aa1SThomas Huth { 59*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_SHA384, 60*da668aa1SThomas Huth .hex_digest = 61*da668aa1SThomas Huth "d218680a6032d33dccd9882d6a6a7164" 62*da668aa1SThomas Huth "64f26623be257a9b2919b185294f4a49" 63*da668aa1SThomas Huth "9e54b190bfd6bc5cedd2cd05c7e65e82", 64*da668aa1SThomas Huth }, 65*da668aa1SThomas Huth { 66*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_SHA512, 67*da668aa1SThomas Huth .hex_digest = 68*da668aa1SThomas Huth "835a4f5b3750b4c1fccfa88da2f746a4" 69*da668aa1SThomas Huth "900160c9f18964309bb736c13b59491b" 70*da668aa1SThomas Huth "8e32d37b724cc5aebb0f554c6338a3b5" 71*da668aa1SThomas Huth "94c4ba26862b2dadb59b7ede1d08d53e", 72*da668aa1SThomas Huth }, 73*da668aa1SThomas Huth { 74*da668aa1SThomas Huth .alg = QCRYPTO_HASH_ALG_RIPEMD160, 75*da668aa1SThomas Huth .hex_digest = 76*da668aa1SThomas Huth "94964ed4c1155b62b668c241d67279e5" 77*da668aa1SThomas Huth "8a711676", 78*da668aa1SThomas Huth }, 79*da668aa1SThomas Huth }; 80*da668aa1SThomas Huth 81*da668aa1SThomas Huth static const char hex[] = "0123456789abcdef"; 82*da668aa1SThomas Huth 83*da668aa1SThomas Huth static void test_hmac_alloc(void) 84*da668aa1SThomas Huth { 85*da668aa1SThomas Huth size_t i; 86*da668aa1SThomas Huth 87*da668aa1SThomas Huth for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 88*da668aa1SThomas Huth QCryptoHmacTestData *data = &test_data[i]; 89*da668aa1SThomas Huth QCryptoHmac *hmac = NULL; 90*da668aa1SThomas Huth uint8_t *result = NULL; 91*da668aa1SThomas Huth size_t resultlen = 0; 92*da668aa1SThomas Huth Error *err = NULL; 93*da668aa1SThomas Huth const char *exp_output = NULL; 94*da668aa1SThomas Huth int ret; 95*da668aa1SThomas Huth size_t j; 96*da668aa1SThomas Huth 97*da668aa1SThomas Huth if (!qcrypto_hmac_supports(data->alg)) { 98*da668aa1SThomas Huth return; 99*da668aa1SThomas Huth } 100*da668aa1SThomas Huth 101*da668aa1SThomas Huth exp_output = data->hex_digest; 102*da668aa1SThomas Huth 103*da668aa1SThomas Huth hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 104*da668aa1SThomas Huth strlen(KEY), &err); 105*da668aa1SThomas Huth g_assert(err == NULL); 106*da668aa1SThomas Huth g_assert(hmac != NULL); 107*da668aa1SThomas Huth 108*da668aa1SThomas Huth ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, 109*da668aa1SThomas Huth strlen(INPUT_TEXT), &result, 110*da668aa1SThomas Huth &resultlen, &err); 111*da668aa1SThomas Huth g_assert(err == NULL); 112*da668aa1SThomas Huth g_assert(ret == 0); 113*da668aa1SThomas Huth 114*da668aa1SThomas Huth for (j = 0; j < resultlen; j++) { 115*da668aa1SThomas Huth g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 116*da668aa1SThomas Huth g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 117*da668aa1SThomas Huth } 118*da668aa1SThomas Huth 119*da668aa1SThomas Huth qcrypto_hmac_free(hmac); 120*da668aa1SThomas Huth 121*da668aa1SThomas Huth g_free(result); 122*da668aa1SThomas Huth } 123*da668aa1SThomas Huth } 124*da668aa1SThomas Huth 125*da668aa1SThomas Huth static void test_hmac_prealloc(void) 126*da668aa1SThomas Huth { 127*da668aa1SThomas Huth size_t i; 128*da668aa1SThomas Huth 129*da668aa1SThomas Huth for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 130*da668aa1SThomas Huth QCryptoHmacTestData *data = &test_data[i]; 131*da668aa1SThomas Huth QCryptoHmac *hmac = NULL; 132*da668aa1SThomas Huth uint8_t *result = NULL; 133*da668aa1SThomas Huth size_t resultlen = 0; 134*da668aa1SThomas Huth Error *err = NULL; 135*da668aa1SThomas Huth const char *exp_output = NULL; 136*da668aa1SThomas Huth int ret; 137*da668aa1SThomas Huth size_t j; 138*da668aa1SThomas Huth 139*da668aa1SThomas Huth if (!qcrypto_hmac_supports(data->alg)) { 140*da668aa1SThomas Huth return; 141*da668aa1SThomas Huth } 142*da668aa1SThomas Huth 143*da668aa1SThomas Huth exp_output = data->hex_digest; 144*da668aa1SThomas Huth 145*da668aa1SThomas Huth resultlen = strlen(exp_output) / 2; 146*da668aa1SThomas Huth result = g_new0(uint8_t, resultlen); 147*da668aa1SThomas Huth 148*da668aa1SThomas Huth hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 149*da668aa1SThomas Huth strlen(KEY), &err); 150*da668aa1SThomas Huth g_assert(err == NULL); 151*da668aa1SThomas Huth g_assert(hmac != NULL); 152*da668aa1SThomas Huth 153*da668aa1SThomas Huth ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, 154*da668aa1SThomas Huth strlen(INPUT_TEXT), &result, 155*da668aa1SThomas Huth &resultlen, &err); 156*da668aa1SThomas Huth g_assert(err == NULL); 157*da668aa1SThomas Huth g_assert(ret == 0); 158*da668aa1SThomas Huth 159*da668aa1SThomas Huth exp_output = data->hex_digest; 160*da668aa1SThomas Huth for (j = 0; j < resultlen; j++) { 161*da668aa1SThomas Huth g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 162*da668aa1SThomas Huth g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 163*da668aa1SThomas Huth } 164*da668aa1SThomas Huth 165*da668aa1SThomas Huth qcrypto_hmac_free(hmac); 166*da668aa1SThomas Huth 167*da668aa1SThomas Huth g_free(result); 168*da668aa1SThomas Huth } 169*da668aa1SThomas Huth } 170*da668aa1SThomas Huth 171*da668aa1SThomas Huth static void test_hmac_iov(void) 172*da668aa1SThomas Huth { 173*da668aa1SThomas Huth size_t i; 174*da668aa1SThomas Huth 175*da668aa1SThomas Huth for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 176*da668aa1SThomas Huth QCryptoHmacTestData *data = &test_data[i]; 177*da668aa1SThomas Huth QCryptoHmac *hmac = NULL; 178*da668aa1SThomas Huth uint8_t *result = NULL; 179*da668aa1SThomas Huth size_t resultlen = 0; 180*da668aa1SThomas Huth Error *err = NULL; 181*da668aa1SThomas Huth const char *exp_output = NULL; 182*da668aa1SThomas Huth int ret; 183*da668aa1SThomas Huth size_t j; 184*da668aa1SThomas Huth struct iovec iov[3] = { 185*da668aa1SThomas Huth { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) }, 186*da668aa1SThomas Huth { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) }, 187*da668aa1SThomas Huth { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) }, 188*da668aa1SThomas Huth }; 189*da668aa1SThomas Huth 190*da668aa1SThomas Huth if (!qcrypto_hmac_supports(data->alg)) { 191*da668aa1SThomas Huth return; 192*da668aa1SThomas Huth } 193*da668aa1SThomas Huth 194*da668aa1SThomas Huth exp_output = data->hex_digest; 195*da668aa1SThomas Huth 196*da668aa1SThomas Huth hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 197*da668aa1SThomas Huth strlen(KEY), &err); 198*da668aa1SThomas Huth g_assert(err == NULL); 199*da668aa1SThomas Huth g_assert(hmac != NULL); 200*da668aa1SThomas Huth 201*da668aa1SThomas Huth ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result, 202*da668aa1SThomas Huth &resultlen, &err); 203*da668aa1SThomas Huth g_assert(err == NULL); 204*da668aa1SThomas Huth g_assert(ret == 0); 205*da668aa1SThomas Huth 206*da668aa1SThomas Huth for (j = 0; j < resultlen; j++) { 207*da668aa1SThomas Huth g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 208*da668aa1SThomas Huth g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 209*da668aa1SThomas Huth } 210*da668aa1SThomas Huth 211*da668aa1SThomas Huth qcrypto_hmac_free(hmac); 212*da668aa1SThomas Huth 213*da668aa1SThomas Huth g_free(result); 214*da668aa1SThomas Huth } 215*da668aa1SThomas Huth } 216*da668aa1SThomas Huth 217*da668aa1SThomas Huth static void test_hmac_digest(void) 218*da668aa1SThomas Huth { 219*da668aa1SThomas Huth size_t i; 220*da668aa1SThomas Huth 221*da668aa1SThomas Huth for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 222*da668aa1SThomas Huth QCryptoHmacTestData *data = &test_data[i]; 223*da668aa1SThomas Huth QCryptoHmac *hmac = NULL; 224*da668aa1SThomas Huth uint8_t *result = NULL; 225*da668aa1SThomas Huth Error *err = NULL; 226*da668aa1SThomas Huth const char *exp_output = NULL; 227*da668aa1SThomas Huth int ret; 228*da668aa1SThomas Huth 229*da668aa1SThomas Huth if (!qcrypto_hmac_supports(data->alg)) { 230*da668aa1SThomas Huth return; 231*da668aa1SThomas Huth } 232*da668aa1SThomas Huth 233*da668aa1SThomas Huth exp_output = data->hex_digest; 234*da668aa1SThomas Huth 235*da668aa1SThomas Huth hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 236*da668aa1SThomas Huth strlen(KEY), &err); 237*da668aa1SThomas Huth g_assert(err == NULL); 238*da668aa1SThomas Huth g_assert(hmac != NULL); 239*da668aa1SThomas Huth 240*da668aa1SThomas Huth ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT, 241*da668aa1SThomas Huth strlen(INPUT_TEXT), (char **)&result, 242*da668aa1SThomas Huth &err); 243*da668aa1SThomas Huth g_assert(err == NULL); 244*da668aa1SThomas Huth g_assert(ret == 0); 245*da668aa1SThomas Huth 246*da668aa1SThomas Huth g_assert_cmpstr((const char *)result, ==, exp_output); 247*da668aa1SThomas Huth 248*da668aa1SThomas Huth qcrypto_hmac_free(hmac); 249*da668aa1SThomas Huth 250*da668aa1SThomas Huth g_free(result); 251*da668aa1SThomas Huth } 252*da668aa1SThomas Huth } 253*da668aa1SThomas Huth 254*da668aa1SThomas Huth int main(int argc, char **argv) 255*da668aa1SThomas Huth { 256*da668aa1SThomas Huth g_test_init(&argc, &argv, NULL); 257*da668aa1SThomas Huth 258*da668aa1SThomas Huth g_assert(qcrypto_init(NULL) == 0); 259*da668aa1SThomas Huth 260*da668aa1SThomas Huth g_test_add_func("/crypto/hmac/iov", test_hmac_iov); 261*da668aa1SThomas Huth g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc); 262*da668aa1SThomas Huth g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc); 263*da668aa1SThomas Huth g_test_add_func("/crypto/hmac/digest", test_hmac_digest); 264*da668aa1SThomas Huth 265*da668aa1SThomas Huth return g_test_run(); 266*da668aa1SThomas Huth } 267