1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /* $Id: hmacsha.c,v 1.7 2020/09/14 08:40:44 florian Exp $ */ 18 19 /* 20 * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384 21 * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and 22 * draft-ietf-dnsext-tsig-sha-01.txt. 23 */ 24 25 #include <string.h> 26 27 #include <isc/hmacsha.h> 28 #include <isc/sha1.h> 29 #include <isc/sha2.h> 30 #include <isc/util.h> 31 32 void 33 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, 34 unsigned int len) 35 { 36 ctx->ctx = HMAC_CTX_new(); 37 RUNTIME_CHECK(ctx->ctx != NULL); 38 RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key, 39 (int) len, EVP_sha1(), NULL) == 1); 40 } 41 42 void 43 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { 44 if (ctx->ctx == NULL) 45 return; 46 HMAC_CTX_free(ctx->ctx); 47 ctx->ctx = NULL; 48 } 49 50 void 51 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, 52 unsigned int len) 53 { 54 RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1); 55 } 56 57 void 58 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 59 unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 60 61 REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 62 63 RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1); 64 HMAC_CTX_free(ctx->ctx); 65 ctx->ctx = NULL; 66 memmove(digest, newdigest, len); 67 explicit_bzero(newdigest, sizeof(newdigest)); 68 } 69 70 void 71 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, 72 unsigned int len) 73 { 74 ctx->ctx = HMAC_CTX_new(); 75 RUNTIME_CHECK(ctx->ctx != NULL); 76 RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key, 77 (int) len, EVP_sha224(), NULL) == 1); 78 } 79 80 void 81 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { 82 if (ctx->ctx == NULL) 83 return; 84 HMAC_CTX_free(ctx->ctx); 85 ctx->ctx = NULL; 86 } 87 88 void 89 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, 90 unsigned int len) 91 { 92 RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1); 93 } 94 95 void 96 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 97 unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 98 99 REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 100 101 RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1); 102 HMAC_CTX_free(ctx->ctx); 103 ctx->ctx = NULL; 104 memmove(digest, newdigest, len); 105 explicit_bzero(newdigest, sizeof(newdigest)); 106 } 107 108 void 109 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, 110 unsigned int len) 111 { 112 ctx->ctx = HMAC_CTX_new(); 113 RUNTIME_CHECK(ctx->ctx != NULL); 114 RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key, 115 (int) len, EVP_sha256(), NULL) == 1); 116 } 117 118 void 119 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { 120 if (ctx->ctx == NULL) 121 return; 122 HMAC_CTX_free(ctx->ctx); 123 ctx->ctx = NULL; 124 } 125 126 void 127 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, 128 unsigned int len) 129 { 130 RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1); 131 } 132 133 void 134 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 135 unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 136 137 REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 138 139 RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1); 140 HMAC_CTX_free(ctx->ctx); 141 ctx->ctx = NULL; 142 memmove(digest, newdigest, len); 143 explicit_bzero(newdigest, sizeof(newdigest)); 144 } 145 146 void 147 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, 148 unsigned int len) 149 { 150 ctx->ctx = HMAC_CTX_new(); 151 RUNTIME_CHECK(ctx->ctx != NULL); 152 RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key, 153 (int) len, EVP_sha384(), NULL) == 1); 154 } 155 156 void 157 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { 158 if (ctx->ctx == NULL) 159 return; 160 HMAC_CTX_free(ctx->ctx); 161 ctx->ctx = NULL; 162 } 163 164 void 165 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, 166 unsigned int len) 167 { 168 RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1); 169 } 170 171 void 172 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 173 unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 174 175 REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 176 177 RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1); 178 HMAC_CTX_free(ctx->ctx); 179 ctx->ctx = NULL; 180 memmove(digest, newdigest, len); 181 explicit_bzero(newdigest, sizeof(newdigest)); 182 } 183 184 void 185 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, 186 unsigned int len) 187 { 188 ctx->ctx = HMAC_CTX_new(); 189 RUNTIME_CHECK(ctx->ctx != NULL); 190 RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key, 191 (int) len, EVP_sha512(), NULL) == 1); 192 } 193 194 void 195 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { 196 if (ctx->ctx == NULL) 197 return; 198 HMAC_CTX_free(ctx->ctx); 199 ctx->ctx = NULL; 200 } 201 202 void 203 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, 204 unsigned int len) 205 { 206 RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1); 207 } 208 209 void 210 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 211 unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 212 213 REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 214 215 RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1); 216 HMAC_CTX_free(ctx->ctx); 217 ctx->ctx = NULL; 218 memmove(digest, newdigest, len); 219 explicit_bzero(newdigest, sizeof(newdigest)); 220 } 221 222 /* 223 * Verify signature - finalize SHA1 operation and reapply SHA1, then 224 * compare to the supplied digest. 225 */ 226 int 227 isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 228 unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 229 230 REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 231 isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); 232 return (timingsafe_bcmp(digest, newdigest, len) == 0); 233 } 234 235 /* 236 * Verify signature - finalize SHA224 operation and reapply SHA224, then 237 * compare to the supplied digest. 238 */ 239 int 240 isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 241 unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 242 243 REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 244 isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); 245 return (timingsafe_bcmp(digest, newdigest, len) == 0); 246 } 247 248 /* 249 * Verify signature - finalize SHA256 operation and reapply SHA256, then 250 * compare to the supplied digest. 251 */ 252 int 253 isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 254 unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 255 256 REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 257 isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); 258 return (timingsafe_bcmp(digest, newdigest, len) == 0); 259 } 260 261 /* 262 * Verify signature - finalize SHA384 operation and reapply SHA384, then 263 * compare to the supplied digest. 264 */ 265 int 266 isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 267 unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 268 269 REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 270 isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); 271 return (timingsafe_bcmp(digest, newdigest, len) == 0); 272 } 273 274 /* 275 * Verify signature - finalize SHA512 operation and reapply SHA512, then 276 * compare to the supplied digest. 277 */ 278 int 279 isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 280 unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 281 282 REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 283 isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); 284 return (timingsafe_bcmp(digest, newdigest, len) == 0); 285 } 286