1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * HMAC low level APIs are deprecated for public use, but still ok for internal 12 * use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include <string.h> 18 #include <stdlib.h> 19 20 #include "internal/nelem.h" 21 22 # include <openssl/hmac.h> 23 # include <openssl/sha.h> 24 # ifndef OPENSSL_NO_MD5 25 # include <openssl/md5.h> 26 # endif 27 28 # ifdef CHARSET_EBCDIC 29 # include <openssl/ebcdic.h> 30 # endif 31 32 #include "testutil.h" 33 34 # ifndef OPENSSL_NO_MD5 35 static struct test_st { 36 const char key[16]; 37 int key_len; 38 const unsigned char data[64]; 39 int data_len; 40 const char *digest; 41 } test[8] = { 42 { 43 "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54, 44 "e9139d1e6ee064ef8cf514fc7dc83e86", 45 }, 46 { 47 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 48 16, "Hi There", 8, 49 "9294727a3638bb1c13f48ef8158bfc9d", 50 }, 51 { 52 "Jefe", 4, "what do ya want for nothing?", 28, 53 "750c783e6ab0b503eaa86e310a5db738", 54 }, 55 { 56 "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 57 16, { 58 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 59 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 60 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 61 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 62 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd 63 }, 50, "56be34521d144c88dbb8c733f0e8b3f6", 64 }, 65 { 66 "", 0, "My test data", 12, 67 "61afdecb95429ef494d61fdee15990cabf0826fc" 68 }, 69 { 70 "", 0, "My test data", 12, 71 "2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" 72 }, 73 { 74 "123456", 6, "My test data", 12, 75 "bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" 76 }, 77 { 78 "12345", 5, "My test data again", 18, 79 "a12396ceddd2a85f4c656bc1e0aa50c78cffde3e" 80 } 81 }; 82 # endif 83 84 static char *pt(unsigned char *md, unsigned int len); 85 86 87 # ifndef OPENSSL_NO_MD5 88 static int test_hmac_md5(int idx) 89 { 90 char *p; 91 # ifdef CHARSET_EBCDIC 92 ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); 93 ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); 94 ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); 95 ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); 96 # endif 97 98 p = pt(HMAC(EVP_md5(), 99 test[idx].key, test[idx].key_len, 100 test[idx].data, test[idx].data_len, NULL, NULL), 101 MD5_DIGEST_LENGTH); 102 103 return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest); 104 } 105 # endif 106 107 static int test_hmac_bad(void) 108 { 109 HMAC_CTX *ctx = NULL; 110 int ret = 0; 111 112 ctx = HMAC_CTX_new(); 113 if (!TEST_ptr(ctx) 114 || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 115 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 116 || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)) 117 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) 118 || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len))) 119 goto err; 120 121 ret = 1; 122 err: 123 HMAC_CTX_free(ctx); 124 return ret; 125 } 126 127 static int test_hmac_run(void) 128 { 129 char *p; 130 HMAC_CTX *ctx = NULL; 131 unsigned char buf[EVP_MAX_MD_SIZE]; 132 unsigned int len; 133 int ret = 0; 134 135 if (!TEST_ptr(ctx = HMAC_CTX_new())) 136 return 0; 137 HMAC_CTX_reset(ctx); 138 139 if (!TEST_ptr(ctx) 140 || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 141 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 142 || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)) 143 || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL))) 144 goto err; 145 146 if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) 147 || !TEST_true(HMAC_Update(ctx, test[4].data, test[4].data_len)) 148 || !TEST_true(HMAC_Final(ctx, buf, &len))) 149 goto err; 150 151 p = pt(buf, len); 152 if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) 153 goto err; 154 155 if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL))) 156 goto err; 157 158 if (!TEST_true(HMAC_Init_ex(ctx, test[5].key, test[5].key_len, EVP_sha256(), NULL)) 159 || !TEST_ptr_eq(HMAC_CTX_get_md(ctx), EVP_sha256()) 160 || !TEST_true(HMAC_Update(ctx, test[5].data, test[5].data_len)) 161 || !TEST_true(HMAC_Final(ctx, buf, &len))) 162 goto err; 163 164 p = pt(buf, len); 165 if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest)) 166 goto err; 167 168 if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) 169 || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) 170 || !TEST_true(HMAC_Final(ctx, buf, &len))) 171 goto err; 172 p = pt(buf, len); 173 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 174 goto err; 175 176 /* Test reusing a key */ 177 if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 178 || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) 179 || !TEST_true(HMAC_Final(ctx, buf, &len))) 180 goto err; 181 p = pt(buf, len); 182 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 183 goto err; 184 185 /* 186 * Test reusing a key where the digest is provided again but is the same as 187 * last time 188 */ 189 if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) 190 || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) 191 || !TEST_true(HMAC_Final(ctx, buf, &len))) 192 goto err; 193 p = pt(buf, len); 194 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 195 goto err; 196 197 ret = 1; 198 err: 199 HMAC_CTX_free(ctx); 200 return ret; 201 } 202 203 204 static int test_hmac_single_shot(void) 205 { 206 char *p; 207 208 /* Test single-shot with NULL key. */ 209 p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len, 210 NULL, NULL), SHA_DIGEST_LENGTH); 211 if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) 212 return 0; 213 214 return 1; 215 } 216 217 218 static int test_hmac_copy(void) 219 { 220 char *p; 221 HMAC_CTX *ctx = NULL, *ctx2 = NULL; 222 unsigned char buf[EVP_MAX_MD_SIZE]; 223 unsigned int len; 224 int ret = 0; 225 226 ctx = HMAC_CTX_new(); 227 ctx2 = HMAC_CTX_new(); 228 if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) 229 goto err; 230 231 if (!TEST_true(HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) 232 || !TEST_true(HMAC_Update(ctx, test[7].data, test[7].data_len)) 233 || !TEST_true(HMAC_CTX_copy(ctx2, ctx)) 234 || !TEST_true(HMAC_Final(ctx2, buf, &len))) 235 goto err; 236 237 p = pt(buf, len); 238 if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest)) 239 goto err; 240 241 ret = 1; 242 err: 243 HMAC_CTX_free(ctx2); 244 HMAC_CTX_free(ctx); 245 return ret; 246 } 247 248 static int test_hmac_copy_uninited(void) 249 { 250 const unsigned char key[24] = {0}; 251 const unsigned char ct[166] = {0}; 252 EVP_PKEY *pkey = NULL; 253 EVP_MD_CTX *ctx = NULL; 254 EVP_MD_CTX *ctx_tmp = NULL; 255 int res = 0; 256 257 if (!TEST_ptr(ctx = EVP_MD_CTX_new()) 258 || !TEST_ptr(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, 259 key, sizeof(key))) 260 || !TEST_true(EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey)) 261 || !TEST_ptr(ctx_tmp = EVP_MD_CTX_new()) 262 || !TEST_true(EVP_MD_CTX_copy(ctx_tmp, ctx))) 263 goto err; 264 EVP_MD_CTX_free(ctx); 265 ctx = ctx_tmp; 266 ctx_tmp = NULL; 267 268 if (!TEST_true(EVP_DigestSignUpdate(ctx, ct, sizeof(ct)))) 269 goto err; 270 res = 1; 271 err: 272 EVP_MD_CTX_free(ctx); 273 EVP_MD_CTX_free(ctx_tmp); 274 EVP_PKEY_free(pkey); 275 return res; 276 } 277 278 # ifndef OPENSSL_NO_MD5 279 static char *pt(unsigned char *md, unsigned int len) 280 { 281 unsigned int i; 282 static char buf[80]; 283 284 if (md == NULL) 285 return NULL; 286 for (i = 0; i < len; i++) 287 sprintf(&(buf[i * 2]), "%02x", md[i]); 288 return buf; 289 } 290 # endif 291 292 int setup_tests(void) 293 { 294 ADD_ALL_TESTS(test_hmac_md5, 4); 295 ADD_TEST(test_hmac_single_shot); 296 ADD_TEST(test_hmac_bad); 297 ADD_TEST(test_hmac_run); 298 ADD_TEST(test_hmac_copy); 299 ADD_TEST(test_hmac_copy_uninited); 300 return 1; 301 } 302 303