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; 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 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 153 exp_output = data->hex_digest; 154 for (j = 0; j < resultlen; j++) { 155 g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 156 g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 157 } 158 159 qcrypto_hmac_free(hmac); 160 161 g_free(result); 162 } 163 } 164 165 static void test_hmac_iov(void) 166 { 167 size_t i; 168 169 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 170 QCryptoHmacTestData *data = &test_data[i]; 171 QCryptoHmac *hmac = NULL; 172 uint8_t *result = NULL; 173 size_t resultlen = 0; 174 const char *exp_output = NULL; 175 int ret; 176 size_t j; 177 struct iovec iov[3] = { 178 { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) }, 179 { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) }, 180 { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) }, 181 }; 182 183 if (!qcrypto_hmac_supports(data->alg)) { 184 return; 185 } 186 187 exp_output = data->hex_digest; 188 189 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 190 strlen(KEY), &error_fatal); 191 g_assert(hmac != NULL); 192 193 ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result, 194 &resultlen, &error_fatal); 195 g_assert(ret == 0); 196 197 for (j = 0; j < resultlen; j++) { 198 g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 199 g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 200 } 201 202 qcrypto_hmac_free(hmac); 203 204 g_free(result); 205 } 206 } 207 208 static void test_hmac_digest(void) 209 { 210 size_t i; 211 212 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 213 QCryptoHmacTestData *data = &test_data[i]; 214 QCryptoHmac *hmac = NULL; 215 uint8_t *result = NULL; 216 const char *exp_output = NULL; 217 int ret; 218 219 if (!qcrypto_hmac_supports(data->alg)) { 220 return; 221 } 222 223 exp_output = data->hex_digest; 224 225 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 226 strlen(KEY), &error_fatal); 227 g_assert(hmac != NULL); 228 229 ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT, 230 strlen(INPUT_TEXT), (char **)&result, 231 &error_fatal); 232 g_assert(ret == 0); 233 234 g_assert_cmpstr((const char *)result, ==, exp_output); 235 236 qcrypto_hmac_free(hmac); 237 238 g_free(result); 239 } 240 } 241 242 int main(int argc, char **argv) 243 { 244 g_test_init(&argc, &argv, NULL); 245 246 g_assert(qcrypto_init(NULL) == 0); 247 248 g_test_add_func("/crypto/hmac/iov", test_hmac_iov); 249 g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc); 250 g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc); 251 g_test_add_func("/crypto/hmac/digest", test_hmac_digest); 252 253 return g_test_run(); 254 } 255