1238438Sdteske/* 2238438Sdteske * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3249746Sdteske * 4238438Sdteske * Licensed under the Apache License 2.0 (the "License"). You may not use 5238438Sdteske * this file except in compliance with the License. You can obtain a copy 6238438Sdteske * in the file LICENSE in the source distribution or at 7238438Sdteske * https://www.openssl.org/source/license.html 8238438Sdteske */ 9238438Sdteske 10238438Sdteske/* 11238438Sdteske * HMAC low level APIs are deprecated for public use, but still ok for internal 12238438Sdteske * use. 13238438Sdteske */ 14238438Sdteske#include "internal/deprecated.h" 15238438Sdteske 16238438Sdteske#include <stdio.h> 17238438Sdteske#include <string.h> 18238438Sdteske#include <stdlib.h> 19238438Sdteske 20238438Sdteske#include "internal/nelem.h" 21238438Sdteske 22238438Sdteske# include <openssl/hmac.h> 23238438Sdteske# include <openssl/sha.h> 24238438Sdteske# ifndef OPENSSL_NO_MD5 25238438Sdteske# include <openssl/md5.h> 26238438Sdteske# endif 27238438Sdteske 28238438Sdteske# ifdef CHARSET_EBCDIC 29238438Sdteske# include <openssl/ebcdic.h> 30238438Sdteske# endif 31240684Sdteske 32240684Sdteske#include "testutil.h" 33244675Sdteske 34240684Sdteske# ifndef OPENSSL_NO_MD5 35240684Sdteskestatic struct test_st { 36240684Sdteske const char key[16]; 37238438Sdteske int key_len; 38240684Sdteske const unsigned char data[64]; 39238438Sdteske int data_len; 40238438Sdteske const char *digest; 41242107Sdteske} test[8] = { 42242107Sdteske { 43243112Sdteske "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54, 44238438Sdteske "e9139d1e6ee064ef8cf514fc7dc83e86", 45238438Sdteske }, 46238438Sdteske { 47238438Sdteske "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 48238438Sdteske 16, "Hi There", 8, 49238438Sdteske "9294727a3638bb1c13f48ef8158bfc9d", 50238438Sdteske }, 51238438Sdteske { 52238438Sdteske "Jefe", 4, "what do ya want for nothing?", 28, 53238438Sdteske "750c783e6ab0b503eaa86e310a5db738", 54238438Sdteske }, 55238438Sdteske { 56238438Sdteske "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 57238438Sdteske 16, { 58238438Sdteske 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 59238438Sdteske 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 60238438Sdteske 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 61238438Sdteske 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 62238438Sdteske 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd 63238438Sdteske }, 50, "56be34521d144c88dbb8c733f0e8b3f6", 64238438Sdteske }, 65238438Sdteske { 66238438Sdteske "", 0, "My test data", 12, 67238438Sdteske "61afdecb95429ef494d61fdee15990cabf0826fc" 68238438Sdteske }, 69238438Sdteske { 70238438Sdteske "", 0, "My test data", 12, 71238438Sdteske "2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" 72238438Sdteske }, 73240768Sdteske { 74240768Sdteske "123456", 6, "My test data", 12, 75238438Sdteske "bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" 76238438Sdteske }, 77238438Sdteske { 78238438Sdteske "12345", 5, "My test data again", 18, 79238438Sdteske "a12396ceddd2a85f4c656bc1e0aa50c78cffde3e" 80241899Sdteske } 81245401Sdteske}; 82242096Sdteske# endif 83238438Sdteske 84238438Sdteskestatic char *pt(unsigned char *md, unsigned int len); 85240768Sdteske 86240768Sdteske#define UC(a) ((const unsigned char *)(a)) 87240768Sdteske 88240768Sdteske 89240768Sdteske# ifndef OPENSSL_NO_MD5 90238438Sdteskestatic int test_hmac_md5(int idx) 91238438Sdteske{ 92238438Sdteske char *p; 93238438Sdteske# ifdef CHARSET_EBCDIC 94238438Sdteske ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); 95238438Sdteske ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); 96238438Sdteske ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); 97238438Sdteske ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); 98238438Sdteske# endif 99238438Sdteske 100249746Sdteske p = pt(HMAC(EVP_md5(), 101238438Sdteske test[idx].key, test[idx].key_len, 102238438Sdteske UC(test[idx].data), test[idx].data_len, NULL, NULL), 103238438Sdteske MD5_DIGEST_LENGTH); 104238438Sdteske 105238438Sdteske return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest); 106238438Sdteske} 107238438Sdteske# endif 108238438Sdteske 109238438Sdteskestatic int test_hmac_bad(void) 110238438Sdteske{ 111238438Sdteske HMAC_CTX *ctx = NULL; 112238438Sdteske int ret = 0; 113238438Sdteske 114238438Sdteske ctx = HMAC_CTX_new(); 115238438Sdteske if (!TEST_ptr(ctx) 116238438Sdteske || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 117241899Sdteske || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 118241899Sdteske || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 119241899Sdteske || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) 120241899Sdteske || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len))) 121238438Sdteske goto err; 122241899Sdteske 123241899Sdteske ret = 1; 124242107Sdteskeerr: 125241899Sdteske HMAC_CTX_free(ctx); 126241899Sdteske return ret; 127241899Sdteske} 128241899Sdteske 129238438Sdteskestatic int test_hmac_run(void) 130241899Sdteske{ 131241899Sdteske char *p; 132241899Sdteske HMAC_CTX *ctx = NULL; 133238438Sdteske unsigned char buf[EVP_MAX_MD_SIZE]; 134238438Sdteske unsigned int len; 135238438Sdteske int ret = 0; 136238438Sdteske 137238438Sdteske if (!TEST_ptr(ctx = HMAC_CTX_new())) 138238438Sdteske return 0; 139238438Sdteske HMAC_CTX_reset(ctx); 140238438Sdteske 141238438Sdteske if (!TEST_ptr(ctx) 142238438Sdteske || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) 143238438Sdteske || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) 144238438Sdteske || !TEST_false(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 145238438Sdteske || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL))) 146238438Sdteske goto err; 147238438Sdteske 148238438Sdteske if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) 149238438Sdteske || !TEST_true(HMAC_Update(ctx, UC(test[4].data), test[4].data_len)) 150238438Sdteske || !TEST_true(HMAC_Final(ctx, buf, &len))) 151238438Sdteske goto err; 152238438Sdteske 153238438Sdteske p = pt(buf, len); 154238438Sdteske if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) 155238438Sdteske 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