| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. | 
|  | 3 | * | 
|  | 4 | * Licensed under the OpenSSL license (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 | #include <stdio.h> | 
|  | 11 | #include <string.h> | 
|  | 12 | #include <stdlib.h> | 
|  | 13 |  | 
|  | 14 | #include "internal/nelem.h" | 
|  | 15 |  | 
|  | 16 | # include <openssl/hmac.h> | 
|  | 17 | # include <openssl/sha.h> | 
|  | 18 | # ifndef OPENSSL_NO_MD5 | 
|  | 19 | #  include <openssl/md5.h> | 
|  | 20 | # endif | 
|  | 21 |  | 
|  | 22 | # ifdef CHARSET_EBCDIC | 
|  | 23 | #  include <openssl/ebcdic.h> | 
|  | 24 | # endif | 
|  | 25 |  | 
|  | 26 | #include "testutil.h" | 
|  | 27 |  | 
|  | 28 | # ifndef OPENSSL_NO_MD5 | 
|  | 29 | static struct test_st { | 
|  | 30 | unsigned char key[16]; | 
|  | 31 | int key_len; | 
|  | 32 | unsigned char data[64]; | 
|  | 33 | int data_len; | 
|  | 34 | unsigned char *digest; | 
|  | 35 | } test[8] = { | 
|  | 36 | { | 
|  | 37 | "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54, | 
|  | 38 | (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86", | 
|  | 39 | }, | 
|  | 40 | { | 
|  | 41 | { | 
|  | 42 | 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | 
|  | 43 | 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, | 
|  | 44 | }, 16, "Hi There", 8, | 
|  | 45 | (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d", | 
|  | 46 | }, | 
|  | 47 | { | 
|  | 48 | "Jefe", 4, "what do ya want for nothing?", 28, | 
|  | 49 | (unsigned char *)"750c783e6ab0b503eaa86e310a5db738", | 
|  | 50 | }, | 
|  | 51 | { | 
|  | 52 | { | 
|  | 53 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, | 
|  | 54 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, | 
|  | 55 | }, 16, { | 
|  | 56 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, | 
|  | 57 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, | 
|  | 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 | 
|  | 61 | }, 50, (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6", | 
|  | 62 | }, | 
|  | 63 | { | 
|  | 64 | "", 0, "My test data", 12, | 
|  | 65 | (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc" | 
|  | 66 | }, | 
|  | 67 | { | 
|  | 68 | "", 0, "My test data", 12, | 
|  | 69 | (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" | 
|  | 70 | }, | 
|  | 71 | { | 
|  | 72 | "123456", 6, "My test data", 12, | 
|  | 73 | (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" | 
|  | 74 | }, | 
|  | 75 | { | 
|  | 76 | "12345", 5, "My test data again", 18, | 
|  | 77 | (unsigned char *)"a12396ceddd2a85f4c656bc1e0aa50c78cffde3e" | 
|  | 78 | } | 
|  | 79 | }; | 
|  | 80 | # endif | 
|  | 81 |  | 
|  | 82 | static char *pt(unsigned char *md, unsigned int len); | 
|  | 83 |  | 
|  | 84 |  | 
|  | 85 | # ifndef OPENSSL_NO_MD5 | 
|  | 86 | static int test_hmac_md5(int idx) | 
|  | 87 | { | 
|  | 88 | char *p; | 
|  | 89 | #  ifdef CHARSET_EBCDIC | 
|  | 90 | ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); | 
|  | 91 | ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); | 
|  | 92 | ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); | 
|  | 93 | ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); | 
|  | 94 | #  endif | 
|  | 95 |  | 
|  | 96 | p = pt(HMAC(EVP_md5(), | 
|  | 97 | test[idx].key, test[idx].key_len, | 
|  | 98 | test[idx].data, test[idx].data_len, NULL, NULL), | 
|  | 99 | MD5_DIGEST_LENGTH); | 
|  | 100 |  | 
|  | 101 | if (!TEST_str_eq(p, (char *)test[idx].digest)) | 
|  | 102 | return 0; | 
|  | 103 |  | 
|  | 104 | return 1; | 
|  | 105 | } | 
|  | 106 | # endif | 
|  | 107 |  | 
|  | 108 | static int test_hmac_bad(void) | 
|  | 109 | { | 
|  | 110 | HMAC_CTX *ctx = NULL; | 
|  | 111 | int ret = 0; | 
|  | 112 |  | 
|  | 113 | ctx = HMAC_CTX_new(); | 
|  | 114 | if (!TEST_ptr(ctx) | 
|  | 115 | || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) | 
|  | 116 | || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) | 
|  | 117 | || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)) | 
|  | 118 | || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) | 
|  | 119 | || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len))) | 
|  | 120 | goto err; | 
|  | 121 |  | 
|  | 122 | ret = 1; | 
|  | 123 | err: | 
|  | 124 | HMAC_CTX_free(ctx); | 
|  | 125 | return ret; | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | static int test_hmac_run(void) | 
|  | 129 | { | 
|  | 130 | char *p; | 
|  | 131 | HMAC_CTX *ctx = NULL; | 
|  | 132 | unsigned char buf[EVP_MAX_MD_SIZE]; | 
|  | 133 | unsigned int len; | 
|  | 134 | int ret = 0; | 
|  | 135 |  | 
|  | 136 | ctx = HMAC_CTX_new(); | 
|  | 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_str_eq(p, (char *)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_str_eq(p, (char *)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_str_eq(p, (char *)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_str_eq(p, (char *)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_str_eq(p, (char *)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 an empty 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_str_eq(p, (char *)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_str_eq(p, (char *)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 | # ifndef OPENSSL_NO_MD5 | 
|  | 249 | static char *pt(unsigned char *md, unsigned int len) | 
|  | 250 | { | 
|  | 251 | unsigned int i; | 
|  | 252 | static char buf[80]; | 
|  | 253 |  | 
|  | 254 | for (i = 0; i < len; i++) | 
|  | 255 | sprintf(&(buf[i * 2]), "%02x", md[i]); | 
|  | 256 | return buf; | 
|  | 257 | } | 
|  | 258 | # endif | 
|  | 259 |  | 
|  | 260 | int setup_tests(void) | 
|  | 261 | { | 
|  | 262 | ADD_ALL_TESTS(test_hmac_md5, 4); | 
|  | 263 | ADD_TEST(test_hmac_single_shot); | 
|  | 264 | ADD_TEST(test_hmac_bad); | 
|  | 265 | ADD_TEST(test_hmac_run); | 
|  | 266 | ADD_TEST(test_hmac_copy); | 
|  | 267 | return 1; | 
|  | 268 | } | 
|  | 269 |  |