crypto_digest_openssl.c (15953B)
1 /* Copyright (c) 2001, Matej Pfajfar. 2 * Copyright (c) 2001-2004, Roger Dingledine. 3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 4 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * \file crypto_digest_openssl.c 9 * \brief Block of functions related with digest and xof utilities and 10 * operations (OpenSSL specific implementations). 11 **/ 12 13 #include "lib/container/smartlist.h" 14 #include "lib/crypt_ops/crypto_digest.h" 15 #include "lib/crypt_ops/crypto_util.h" 16 #include "lib/log/log.h" 17 #include "lib/log/util_bug.h" 18 19 #include "keccak-tiny/keccak-tiny.h" 20 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "lib/arch/bytes.h" 25 26 #include "lib/crypt_ops/crypto_openssl_mgt.h" 27 28 DISABLE_GCC_WARNING("-Wredundant-decls") 29 30 #include <openssl/hmac.h> 31 #include <openssl/sha.h> 32 33 ENABLE_GCC_WARNING("-Wredundant-decls") 34 35 /* Crypto digest functions */ 36 37 /** Compute the SHA1 digest of the <b>len</b> bytes on data stored in 38 * <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>. 39 * Return 0 on success, -1 on failure. 40 */ 41 MOCK_IMPL(int, 42 crypto_digest,(char *digest, const char *m, size_t len)) 43 { 44 tor_assert(m); 45 tor_assert(digest); 46 if (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL) { 47 return -1; 48 } 49 return 0; 50 } 51 52 /** Compute a 256-bit digest of <b>len</b> bytes in data stored in <b>m</b>, 53 * using the algorithm <b>algorithm</b>. Write the DIGEST_LEN256-byte result 54 * into <b>digest</b>. Return 0 on success, -1 on failure. */ 55 int 56 crypto_digest256(char *digest, const char *m, size_t len, 57 digest_algorithm_t algorithm) 58 { 59 tor_assert(m); 60 tor_assert(digest); 61 tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256); 62 63 int ret = 0; 64 if (algorithm == DIGEST_SHA256) { 65 ret = (SHA256((const uint8_t*)m,len,(uint8_t*)digest) != NULL); 66 } else { 67 #ifdef OPENSSL_HAS_SHA3 68 unsigned int dlen = DIGEST256_LEN; 69 ret = EVP_Digest(m, len, (uint8_t*)digest, &dlen, EVP_sha3_256(), NULL); 70 #else 71 ret = (sha3_256((uint8_t *)digest, DIGEST256_LEN,(const uint8_t *)m, len) 72 > -1); 73 #endif /* defined(OPENSSL_HAS_SHA3) */ 74 } 75 76 if (!ret) 77 return -1; 78 return 0; 79 } 80 81 /** Compute a 512-bit digest of <b>len</b> bytes in data stored in <b>m</b>, 82 * using the algorithm <b>algorithm</b>. Write the DIGEST_LEN512-byte result 83 * into <b>digest</b>. Return 0 on success, -1 on failure. */ 84 int 85 crypto_digest512(char *digest, const char *m, size_t len, 86 digest_algorithm_t algorithm) 87 { 88 tor_assert(m); 89 tor_assert(digest); 90 tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512); 91 92 int ret = 0; 93 if (algorithm == DIGEST_SHA512) { 94 ret = (SHA512((const unsigned char*)m,len,(unsigned char*)digest) 95 != NULL); 96 } else { 97 #ifdef OPENSSL_HAS_SHA3 98 unsigned int dlen = DIGEST512_LEN; 99 ret = EVP_Digest(m, len, (uint8_t*)digest, &dlen, EVP_sha3_512(), NULL); 100 #else 101 ret = (sha3_512((uint8_t*)digest, DIGEST512_LEN, (const uint8_t*)m, len) 102 > -1); 103 #endif /* defined(OPENSSL_HAS_SHA3) */ 104 } 105 106 if (!ret) 107 return -1; 108 return 0; 109 } 110 111 /** Intermediate information about the digest of a stream of data. */ 112 struct crypto_digest_t { 113 digest_algorithm_t algorithm; /**< Which algorithm is in use? */ 114 /** State for the digest we're using. Only one member of the 115 * union is usable, depending on the value of <b>algorithm</b>. Note also 116 * that space for other members might not even be allocated! 117 */ 118 union { 119 SHA_CTX sha1; /**< state for SHA1 */ 120 SHA256_CTX sha2; /**< state for SHA256 */ 121 SHA512_CTX sha512; /**< state for SHA512 */ 122 #ifdef OPENSSL_HAS_SHA3 123 EVP_MD_CTX *md; 124 #else 125 keccak_state sha3; /**< state for SHA3-[256,512] */ 126 #endif 127 } d; 128 }; 129 130 #ifdef TOR_UNIT_TESTS 131 132 digest_algorithm_t 133 crypto_digest_get_algorithm(crypto_digest_t *digest) 134 { 135 tor_assert(digest); 136 137 return digest->algorithm; 138 } 139 140 #endif /* defined(TOR_UNIT_TESTS) */ 141 142 /** 143 * Return the number of bytes we need to malloc in order to get a 144 * crypto_digest_t for <b>alg</b>, or the number of bytes we need to wipe 145 * when we free one. 146 */ 147 static size_t 148 crypto_digest_alloc_bytes(digest_algorithm_t alg) 149 { 150 /** Helper: returns the number of bytes in the 'f' field of 'st' */ 151 #define STRUCT_FIELD_SIZE(st, f) (sizeof( ((st*)0)->f )) 152 /** Gives the length of crypto_digest_t through the end of the field 'd' */ 153 #define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \ 154 STRUCT_FIELD_SIZE(crypto_digest_t, f)) 155 switch (alg) { 156 case DIGEST_SHA1: 157 return END_OF_FIELD(d.sha1); 158 case DIGEST_SHA256: 159 return END_OF_FIELD(d.sha2); 160 case DIGEST_SHA512: 161 return END_OF_FIELD(d.sha512); 162 #ifdef OPENSSL_HAS_SHA3 163 case DIGEST_SHA3_256: FALLTHROUGH; 164 case DIGEST_SHA3_512: 165 return END_OF_FIELD(d.md); 166 #else 167 case DIGEST_SHA3_256: FALLTHROUGH; 168 case DIGEST_SHA3_512: 169 return END_OF_FIELD(d.sha3); 170 #endif /* defined(OPENSSL_HAS_SHA3) */ 171 default: 172 tor_assert(0); // LCOV_EXCL_LINE 173 return 0; // LCOV_EXCL_LINE 174 } 175 #undef END_OF_FIELD 176 #undef STRUCT_FIELD_SIZE 177 } 178 179 /** 180 * Internal function: create and return a new digest object for 'algorithm'. 181 * Does not typecheck the algorithm. 182 */ 183 static crypto_digest_t * 184 crypto_digest_new_internal(digest_algorithm_t algorithm) 185 { 186 crypto_digest_t *r = tor_malloc(crypto_digest_alloc_bytes(algorithm)); 187 r->algorithm = algorithm; 188 189 switch (algorithm) 190 { 191 case DIGEST_SHA1: 192 SHA1_Init(&r->d.sha1); 193 break; 194 case DIGEST_SHA256: 195 SHA256_Init(&r->d.sha2); 196 break; 197 case DIGEST_SHA512: 198 SHA512_Init(&r->d.sha512); 199 break; 200 #ifdef OPENSSL_HAS_SHA3 201 case DIGEST_SHA3_256: 202 r->d.md = EVP_MD_CTX_new(); 203 if (!EVP_DigestInit(r->d.md, EVP_sha3_256())) { 204 crypto_digest_free(r); 205 return NULL; 206 } 207 break; 208 case DIGEST_SHA3_512: 209 r->d.md = EVP_MD_CTX_new(); 210 if (!EVP_DigestInit(r->d.md, EVP_sha3_512())) { 211 crypto_digest_free(r); 212 return NULL; 213 } 214 break; 215 #else /* !defined(OPENSSL_HAS_SHA3) */ 216 case DIGEST_SHA3_256: 217 keccak_digest_init(&r->d.sha3, 256); 218 break; 219 case DIGEST_SHA3_512: 220 keccak_digest_init(&r->d.sha3, 512); 221 break; 222 #endif /* defined(OPENSSL_HAS_SHA3) */ 223 default: 224 tor_assert_unreached(); 225 } 226 227 return r; 228 } 229 230 /** Allocate and return a new digest object to compute SHA1 digests. 231 */ 232 crypto_digest_t * 233 crypto_digest_new(void) 234 { 235 return crypto_digest_new_internal(DIGEST_SHA1); 236 } 237 238 /** Allocate and return a new digest object to compute 256-bit digests 239 * using <b>algorithm</b>. 240 * 241 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest256_new` 242 * C_RUST_COUPLED: `crypto::digest::Sha256::default` 243 */ 244 crypto_digest_t * 245 crypto_digest256_new(digest_algorithm_t algorithm) 246 { 247 tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256); 248 return crypto_digest_new_internal(algorithm); 249 } 250 251 /** Allocate and return a new digest object to compute 512-bit digests 252 * using <b>algorithm</b>. */ 253 crypto_digest_t * 254 crypto_digest512_new(digest_algorithm_t algorithm) 255 { 256 tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512); 257 return crypto_digest_new_internal(algorithm); 258 } 259 260 /** Deallocate a digest object. 261 */ 262 void 263 crypto_digest_free_(crypto_digest_t *digest) 264 { 265 if (!digest) 266 return; 267 #ifdef OPENSSL_HAS_SHA3 268 if (digest->algorithm == DIGEST_SHA3_256 || 269 digest->algorithm == DIGEST_SHA3_512) { 270 if (digest->d.md) { 271 EVP_MD_CTX_free(digest->d.md); 272 } 273 } 274 #endif /* defined(OPENSSL_HAS_SHA3) */ 275 size_t bytes = crypto_digest_alloc_bytes(digest->algorithm); 276 memwipe(digest, 0, bytes); 277 tor_free(digest); 278 } 279 280 /** Add <b>len</b> bytes from <b>data</b> to the digest object. 281 * 282 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_add_bytess` 283 * C_RUST_COUPLED: `crypto::digest::Sha256::process` 284 */ 285 void 286 crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, 287 size_t len) 288 { 289 tor_assert(digest); 290 tor_assert(data); 291 /* Using the SHA*_*() calls directly means we don't support doing 292 * SHA in hardware. But so far the delay of getting the question 293 * to the hardware, and hearing the answer, is likely higher than 294 * just doing it ourselves. Hashes are fast. 295 */ 296 switch (digest->algorithm) { 297 case DIGEST_SHA1: 298 SHA1_Update(&digest->d.sha1, (void*)data, len); 299 break; 300 case DIGEST_SHA256: 301 SHA256_Update(&digest->d.sha2, (void*)data, len); 302 break; 303 case DIGEST_SHA512: 304 SHA512_Update(&digest->d.sha512, (void*)data, len); 305 break; 306 #ifdef OPENSSL_HAS_SHA3 307 case DIGEST_SHA3_256: FALLTHROUGH; 308 case DIGEST_SHA3_512: { 309 int r = EVP_DigestUpdate(digest->d.md, data, len); 310 tor_assert(r); 311 } 312 break; 313 #else /* !defined(OPENSSL_HAS_SHA3) */ 314 case DIGEST_SHA3_256: FALLTHROUGH; 315 case DIGEST_SHA3_512: 316 keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len); 317 break; 318 #endif /* defined(OPENSSL_HAS_SHA3) */ 319 default: 320 /* LCOV_EXCL_START */ 321 tor_fragile_assert(); 322 break; 323 /* LCOV_EXCL_STOP */ 324 } 325 } 326 327 /** Compute the hash of the data that has been passed to the digest 328 * object; write the first out_len bytes of the result to <b>out</b>. 329 * <b>out_len</b> must be \<= DIGEST512_LEN. 330 * 331 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_get_digest` 332 * C_RUST_COUPLED: `impl digest::FixedOutput for Sha256` 333 */ 334 void 335 crypto_digest_get_digest(crypto_digest_t *digest, 336 char *out, size_t out_len) 337 { 338 unsigned char r[DIGEST512_LEN]; 339 tor_assert(digest); 340 tor_assert(out); 341 tor_assert(out_len <= crypto_digest_algorithm_get_length(digest->algorithm)); 342 343 /* The SHA-3 code handles copying into a temporary ctx, and also can handle 344 * short output buffers by truncating appropriately. */ 345 if (digest->algorithm == DIGEST_SHA3_256 || 346 digest->algorithm == DIGEST_SHA3_512) { 347 #ifdef OPENSSL_HAS_SHA3 348 unsigned dlen = (unsigned) 349 crypto_digest_algorithm_get_length(digest->algorithm); 350 EVP_MD_CTX *tmp = EVP_MD_CTX_new(); 351 EVP_MD_CTX_copy(tmp, digest->d.md); 352 memset(r, 0xff, sizeof(r)); 353 int res = EVP_DigestFinal(tmp, r, &dlen); 354 EVP_MD_CTX_free(tmp); 355 tor_assert(res == 1); 356 goto done; 357 #else /* !defined(OPENSSL_HAS_SHA3) */ 358 /* Tiny-Keccak handles copying into a temporary ctx, and also can handle 359 * short output buffers by truncating appropriately. */ 360 keccak_digest_sum(&digest->d.sha3, (uint8_t *)out, out_len); 361 return; 362 #endif /* defined(OPENSSL_HAS_SHA3) */ 363 } 364 365 const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm); 366 crypto_digest_t tmpenv; 367 /* memcpy into a temporary ctx, since SHA*_Final clears the context */ 368 memcpy(&tmpenv, digest, alloc_bytes); 369 switch (digest->algorithm) { 370 case DIGEST_SHA1: 371 SHA1_Final(r, &tmpenv.d.sha1); 372 break; 373 case DIGEST_SHA256: 374 SHA256_Final(r, &tmpenv.d.sha2); 375 break; 376 case DIGEST_SHA512: 377 SHA512_Final(r, &tmpenv.d.sha512); 378 break; 379 //LCOV_EXCL_START 380 case DIGEST_SHA3_256: FALLTHROUGH; 381 case DIGEST_SHA3_512: 382 default: 383 log_warn(LD_BUG, "Handling unexpected algorithm %d", digest->algorithm); 384 /* This is fatal, because it should never happen. */ 385 tor_assert_unreached(); 386 break; 387 //LCOV_EXCL_STOP 388 } 389 #ifdef OPENSSL_HAS_SHA3 390 done: 391 #endif 392 memcpy(out, r, out_len); 393 memwipe(r, 0, sizeof(r)); 394 } 395 396 /** Allocate and return a new digest object with the same state as 397 * <b>digest</b> 398 * 399 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_dup` 400 * C_RUST_COUPLED: `impl Clone for crypto::digest::Sha256` 401 */ 402 crypto_digest_t * 403 crypto_digest_dup(const crypto_digest_t *digest) 404 { 405 tor_assert(digest); 406 const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm); 407 crypto_digest_t *result = tor_memdup(digest, alloc_bytes); 408 409 #ifdef OPENSSL_HAS_SHA3 410 if (digest->algorithm == DIGEST_SHA3_256 || 411 digest->algorithm == DIGEST_SHA3_512) { 412 result->d.md = EVP_MD_CTX_new(); 413 EVP_MD_CTX_copy(result->d.md, digest->d.md); 414 } 415 #endif /* defined(OPENSSL_HAS_SHA3) */ 416 return result; 417 } 418 419 /** Temporarily save the state of <b>digest</b> in <b>checkpoint</b>. 420 * Asserts that <b>digest</b> is a SHA1 digest object. 421 */ 422 void 423 crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, 424 const crypto_digest_t *digest) 425 { 426 const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm); 427 tor_assert(bytes <= sizeof(checkpoint->mem)); 428 memcpy(checkpoint->mem, digest, bytes); 429 } 430 431 /** Restore the state of <b>digest</b> from <b>checkpoint</b>. 432 * Asserts that <b>digest</b> is a SHA1 digest object. Requires that the 433 * state was previously stored with crypto_digest_checkpoint() */ 434 void 435 crypto_digest_restore(crypto_digest_t *digest, 436 const crypto_digest_checkpoint_t *checkpoint) 437 { 438 const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm); 439 memcpy(digest, checkpoint->mem, bytes); 440 } 441 442 /** Replace the state of the digest object <b>into</b> with the state 443 * of the digest object <b>from</b>. Requires that 'into' and 'from' 444 * have the same digest type. 445 */ 446 void 447 crypto_digest_assign(crypto_digest_t *into, 448 const crypto_digest_t *from) 449 { 450 tor_assert(into); 451 tor_assert(from); 452 tor_assert(into->algorithm == from->algorithm); 453 const size_t alloc_bytes = crypto_digest_alloc_bytes(from->algorithm); 454 455 #ifdef OPENSSL_HAS_SHA3 456 if (from->algorithm == DIGEST_SHA3_256 || 457 from->algorithm == DIGEST_SHA3_512) { 458 EVP_MD_CTX_copy(into->d.md, from->d.md); 459 return; 460 } 461 #endif /* defined(OPENSSL_HAS_SHA3) */ 462 463 memcpy(into,from,alloc_bytes); 464 } 465 466 /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest 467 * at <b>digest_out</b> to the hash of the concatenation of those strings, 468 * plus the optional string <b>append</b>, computed with the algorithm 469 * <b>alg</b>. 470 * <b>out_len</b> must be \<= DIGEST512_LEN. */ 471 void 472 crypto_digest_smartlist(char *digest_out, size_t len_out, 473 const smartlist_t *lst, 474 const char *append, 475 digest_algorithm_t alg) 476 { 477 crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg); 478 } 479 480 /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest 481 * at <b>digest_out</b> to the hash of the concatenation of: the 482 * optional string <b>prepend</b>, those strings, 483 * and the optional string <b>append</b>, computed with the algorithm 484 * <b>alg</b>. 485 * <b>len_out</b> must be \<= DIGEST512_LEN. */ 486 void 487 crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, 488 const char *prepend, 489 const smartlist_t *lst, 490 const char *append, 491 digest_algorithm_t alg) 492 { 493 crypto_digest_t *d = crypto_digest_new_internal(alg); 494 if (prepend) 495 crypto_digest_add_bytes(d, prepend, strlen(prepend)); 496 SMARTLIST_FOREACH(lst, const char *, cp, 497 crypto_digest_add_bytes(d, cp, strlen(cp))); 498 if (append) 499 crypto_digest_add_bytes(d, append, strlen(append)); 500 crypto_digest_get_digest(d, digest_out, len_out); 501 crypto_digest_free(d); 502 } 503 504 /** Compute the HMAC-SHA-256 of the <b>msg_len</b> bytes in <b>msg</b>, using 505 * the <b>key</b> of length <b>key_len</b>. Store the DIGEST256_LEN-byte 506 * result in <b>hmac_out</b>. Asserts on failure. 507 */ 508 void 509 crypto_hmac_sha256(char *hmac_out, 510 const char *key, size_t key_len, 511 const char *msg, size_t msg_len) 512 { 513 /* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */ 514 tor_assert(key_len < INT_MAX); 515 tor_assert(msg_len < INT_MAX); 516 tor_assert(hmac_out); 517 unsigned char *rv = NULL; 518 rv = HMAC(EVP_sha256(), key, (int)key_len, (unsigned char*)msg, (int)msg_len, 519 (unsigned char*)hmac_out, NULL); 520 tor_assert(rv); 521 }