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 35static 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 84static char *pt(unsigned char *md, unsigned int len); 85 86#define UC(a) ((const unsigned char *)(a)) 87 88 89# ifndef OPENSSL_NO_MD5 90static int test_hmac_md5(int idx) 91{ 92 char *p; 93# ifdef CHARSET_EBCDIC 94 ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); 95 ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); 96 ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); 97 ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); 98# endif 99 100 p = pt(HMAC(EVP_md5(), 101 test[idx].key, test[idx].key_len, 102 UC(test[idx].data), test[idx].data_len, NULL, NULL), 103 MD5_DIGEST_LENGTH); 104 105 return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest); 106} 107# endif 108 109static int test_hmac_bad(void) 110{ 111 HMAC_CTX *ctx = NULL; 112 int ret = 0; 113 114 ctx = HMAC_CTX_new(); 115 if (!TEST_ptr(ctx) 116 || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 117 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 118 || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 119 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) 120 || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len))) 121 goto err; 122 123 ret = 1; 124err: 125 HMAC_CTX_free(ctx); 126 return ret; 127} 128 129static int test_hmac_run(void) 130{ 131 char *p; 132 HMAC_CTX *ctx = NULL; 133 unsigned char buf[EVP_MAX_MD_SIZE]; 134 unsigned int len; 135 int ret = 0; 136 137 if (!TEST_ptr(ctx = HMAC_CTX_new())) 138 return 0; 139 HMAC_CTX_reset(ctx); 140 141 if (!TEST_ptr(ctx) 142 || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 143 || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 144 || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 145 || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL))) 146 goto err; 147 148 if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) 149 || !TEST_true(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 150 || !TEST_true(HMAC_Final(ctx, buf, &len))) 151 goto err; 152 153 p = pt(buf, len); 154 if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) 155 goto err; 156 157 if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL))) 158 goto err; 159 160 if (!TEST_true(HMAC_Init_ex(ctx, test[5].key, test[5].key_len, EVP_sha256(), NULL)) 161 || !TEST_ptr_eq(HMAC_CTX_get_md(ctx), EVP_sha256()) 162 || !TEST_true(HMAC_Update(ctx, UC(test[5].data), test[5].data_len)) 163 || !TEST_true(HMAC_Final(ctx, buf, &len))) 164 goto err; 165 166 p = pt(buf, len); 167 if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest)) 168 goto err; 169 170 if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) 171 || !TEST_true(HMAC_Update(ctx, UC(test[6].data), test[6].data_len)) 172 || !TEST_true(HMAC_Final(ctx, buf, &len))) 173 goto err; 174 p = pt(buf, len); 175 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 176 goto err; 177 178 /* Test reusing a key */ 179 if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 180 || !TEST_true(HMAC_Update(ctx, UC(test[6].data), test[6].data_len)) 181 || !TEST_true(HMAC_Final(ctx, buf, &len))) 182 goto err; 183 p = pt(buf, len); 184 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 185 goto err; 186 187 /* 188 * Test reusing a key where the digest is provided again but is the same as 189 * last time 190 */ 191 if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) 192 || !TEST_true(HMAC_Update(ctx, UC(test[6].data), test[6].data_len)) 193 || !TEST_true(HMAC_Final(ctx, buf, &len))) 194 goto err; 195 p = pt(buf, len); 196 if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) 197 goto err; 198 199 ret = 1; 200err: 201 HMAC_CTX_free(ctx); 202 return ret; 203} 204 205 206static int test_hmac_single_shot(void) 207{ 208 char *p; 209 210 /* Test single-shot with NULL key. */ 211 p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len, 212 NULL, NULL), SHA_DIGEST_LENGTH); 213 if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) 214 return 0; 215 216 return 1; 217} 218 219 220static int test_hmac_copy(void) 221{ 222 char *p; 223 HMAC_CTX *ctx = NULL, *ctx2 = NULL; 224 unsigned char buf[EVP_MAX_MD_SIZE]; 225 unsigned int len; 226 int ret = 0; 227 228 ctx = HMAC_CTX_new(); 229 ctx2 = HMAC_CTX_new(); 230 if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) 231 goto err; 232 233 if (!TEST_true(HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) 234 || !TEST_true(HMAC_Update(ctx, UC(test[7].data), test[7].data_len)) 235 || !TEST_true(HMAC_CTX_copy(ctx2, ctx)) 236 || !TEST_true(HMAC_Final(ctx2, buf, &len))) 237 goto err; 238 239 p = pt(buf, len); 240 if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest)) 241 goto err; 242 243 ret = 1; 244err: 245 HMAC_CTX_free(ctx2); 246 HMAC_CTX_free(ctx); 247 return ret; 248} 249 250static int test_hmac_copy_uninited(void) 251{ 252 const unsigned char key[24] = {0}; 253 const unsigned char ct[166] = {0}; 254 EVP_PKEY *pkey = NULL; 255 EVP_MD_CTX *ctx = NULL; 256 EVP_MD_CTX *ctx_tmp = NULL; 257 int res = 0; 258 259 if (!TEST_ptr(ctx = EVP_MD_CTX_new()) 260 || !TEST_ptr(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, 261 key, sizeof(key))) 262 || !TEST_true(EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey)) 263 || !TEST_ptr(ctx_tmp = EVP_MD_CTX_new()) 264 || !TEST_true(EVP_MD_CTX_copy(ctx_tmp, ctx))) 265 goto err; 266 EVP_MD_CTX_free(ctx); 267 ctx = ctx_tmp; 268 ctx_tmp = NULL; 269 270 if (!TEST_true(EVP_DigestSignUpdate(ctx, ct, sizeof(ct)))) 271 goto err; 272 res = 1; 273 err: 274 EVP_MD_CTX_free(ctx); 275 EVP_MD_CTX_free(ctx_tmp); 276 EVP_PKEY_free(pkey); 277 return res; 278} 279 280# ifndef OPENSSL_NO_MD5 281static char *pt(unsigned char *md, unsigned int len) 282{ 283 unsigned int i; 284 static char buf[80]; 285 286 if (md == NULL) 287 return NULL; 288 for (i = 0; i < len; i++) 289 sprintf(&(buf[i * 2]), "%02x", md[i]); 290 return buf; 291} 292# endif 293 294int setup_tests(void) 295{ 296 ADD_ALL_TESTS(test_hmac_md5, 4); 297 ADD_TEST(test_hmac_single_shot); 298 ADD_TEST(test_hmac_bad); 299 ADD_TEST(test_hmac_run); 300 ADD_TEST(test_hmac_copy); 301 ADD_TEST(test_hmac_copy_uninited); 302 return 1; 303} 304 305