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