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 #ifdef CONFIG_CRYPTO_SM3 80 { 81 .alg = QCRYPTO_HASH_ALGO_SM3, 82 .hex_digest = 83 "760e3799332bc913819b930085360ddb" 84 "c05529261313d5b15b75bab4fd7ae91e", 85 }, 86 #endif 87 }; 88 89 static const char hex[] = "0123456789abcdef"; 90 91 static void test_hmac_alloc(void) 92 { 93 size_t i; 94 95 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 96 QCryptoHmacTestData *data = &test_data[i]; 97 QCryptoHmac *hmac = NULL; 98 uint8_t *result = NULL; 99 size_t resultlen = 0; 100 const char *exp_output = NULL; 101 int ret; 102 size_t j; 103 104 if (!qcrypto_hmac_supports(data->alg)) { 105 return; 106 } 107 108 exp_output = data->hex_digest; 109 110 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 111 strlen(KEY), &error_fatal); 112 g_assert(hmac != NULL); 113 114 ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, 115 strlen(INPUT_TEXT), &result, 116 &resultlen, &error_fatal); 117 g_assert(ret == 0); 118 119 for (j = 0; j < resultlen; j++) { 120 g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 121 g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 122 } 123 124 qcrypto_hmac_free(hmac); 125 126 g_free(result); 127 } 128 } 129 130 static void test_hmac_prealloc(void) 131 { 132 size_t i; 133 134 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 135 QCryptoHmacTestData *data = &test_data[i]; 136 QCryptoHmac *hmac = NULL; 137 uint8_t *result = NULL, *origresult = NULL; 138 size_t resultlen = 0; 139 const char *exp_output = NULL; 140 int ret; 141 size_t j; 142 143 if (!qcrypto_hmac_supports(data->alg)) { 144 return; 145 } 146 147 exp_output = data->hex_digest; 148 149 resultlen = strlen(exp_output) / 2; 150 origresult = result = g_new0(uint8_t, resultlen); 151 152 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 153 strlen(KEY), &error_fatal); 154 g_assert(hmac != NULL); 155 156 ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, 157 strlen(INPUT_TEXT), &result, 158 &resultlen, &error_fatal); 159 g_assert(ret == 0); 160 /* Validate that our pre-allocated pointer was not replaced */ 161 g_assert(result == origresult); 162 163 exp_output = data->hex_digest; 164 for (j = 0; j < resultlen; j++) { 165 g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 166 g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 167 } 168 169 qcrypto_hmac_free(hmac); 170 171 g_free(result); 172 } 173 } 174 175 static void test_hmac_iov(void) 176 { 177 size_t i; 178 179 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 180 QCryptoHmacTestData *data = &test_data[i]; 181 QCryptoHmac *hmac = NULL; 182 uint8_t *result = NULL; 183 size_t resultlen = 0; 184 const char *exp_output = NULL; 185 int ret; 186 size_t j; 187 struct iovec iov[3] = { 188 { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) }, 189 { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) }, 190 { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) }, 191 }; 192 193 if (!qcrypto_hmac_supports(data->alg)) { 194 return; 195 } 196 197 exp_output = data->hex_digest; 198 199 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 200 strlen(KEY), &error_fatal); 201 g_assert(hmac != NULL); 202 203 ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result, 204 &resultlen, &error_fatal); 205 g_assert(ret == 0); 206 207 for (j = 0; j < resultlen; j++) { 208 g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); 209 g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); 210 } 211 212 qcrypto_hmac_free(hmac); 213 214 g_free(result); 215 } 216 } 217 218 static void test_hmac_digest(void) 219 { 220 size_t i; 221 222 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 223 QCryptoHmacTestData *data = &test_data[i]; 224 QCryptoHmac *hmac = NULL; 225 uint8_t *result = NULL; 226 const char *exp_output = NULL; 227 int ret; 228 229 if (!qcrypto_hmac_supports(data->alg)) { 230 return; 231 } 232 233 exp_output = data->hex_digest; 234 235 hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, 236 strlen(KEY), &error_fatal); 237 g_assert(hmac != NULL); 238 239 ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT, 240 strlen(INPUT_TEXT), (char **)&result, 241 &error_fatal); 242 g_assert(ret == 0); 243 244 g_assert_cmpstr((const char *)result, ==, exp_output); 245 246 qcrypto_hmac_free(hmac); 247 248 g_free(result); 249 } 250 } 251 252 int main(int argc, char **argv) 253 { 254 g_test_init(&argc, &argv, NULL); 255 256 g_assert(qcrypto_init(NULL) == 0); 257 258 g_test_add_func("/crypto/hmac/iov", test_hmac_iov); 259 g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc); 260 g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc); 261 g_test_add_func("/crypto/hmac/digest", test_hmac_digest); 262 263 return g_test_run(); 264 } 265