mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Add basic support for SHA256.
This adds an openssl 0.9.8 dependency. Let's see if anybody cares.
This commit is contained in:
parent
b9e45cc508
commit
f57883a39e
@ -1394,9 +1394,23 @@ crypto_digest(char *digest, const char *m, size_t len)
|
||||
return (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
|
||||
}
|
||||
|
||||
int
|
||||
crypto_digest256(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm)
|
||||
{
|
||||
tor_assert(m);
|
||||
tor_assert(digest);
|
||||
tor_assert(algorithm == DIGEST_SHA256);
|
||||
return (SHA256((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
|
||||
}
|
||||
|
||||
/** Intermediate information about the digest of a stream of data. */
|
||||
struct crypto_digest_env_t {
|
||||
SHA_CTX d;
|
||||
union {
|
||||
SHA_CTX sha1;
|
||||
SHA256_CTX sha2;
|
||||
} d;
|
||||
digest_algorithm_t algorithm : 8;
|
||||
};
|
||||
|
||||
/** Allocate and return a new digest object.
|
||||
@ -1406,7 +1420,19 @@ crypto_new_digest_env(void)
|
||||
{
|
||||
crypto_digest_env_t *r;
|
||||
r = tor_malloc(sizeof(crypto_digest_env_t));
|
||||
SHA1_Init(&r->d);
|
||||
SHA1_Init(&r->d.sha1);
|
||||
r->algorithm = DIGEST_SHA1;
|
||||
return r;
|
||||
}
|
||||
|
||||
crypto_digest_env_t *
|
||||
crypto_new_digest256_env(digest_algorithm_t algorithm)
|
||||
{
|
||||
crypto_digest_env_t *r;
|
||||
tor_assert(algorithm == DIGEST_SHA256);
|
||||
r = tor_malloc(sizeof(crypto_digest_env_t));
|
||||
SHA256_Init(&r->d.sha2);
|
||||
r->algorithm = algorithm;
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1427,30 +1453,51 @@ crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
|
||||
{
|
||||
tor_assert(digest);
|
||||
tor_assert(data);
|
||||
/* Using the SHA1_*() calls directly means we don't support doing
|
||||
* SHA1 in hardware. But so far the delay of getting the question
|
||||
/* Using the SHA*_*() calls directly means we don't support doing
|
||||
* SHA in hardware. But so far the delay of getting the question
|
||||
* to the hardware, and hearing the answer, is likely higher than
|
||||
* just doing it ourselves. Hashes are fast.
|
||||
*/
|
||||
SHA1_Update(&digest->d, (void*)data, len);
|
||||
switch (digest->algorithm) {
|
||||
case DIGEST_SHA1:
|
||||
SHA1_Update(&digest->d.sha1, (void*)data, len);
|
||||
break;
|
||||
case DIGEST_SHA256:
|
||||
SHA256_Update(&digest->d.sha2, (void*)data, len);
|
||||
break;
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute the hash of the data that has been passed to the digest
|
||||
* object; write the first out_len bytes of the result to <b>out</b>.
|
||||
* <b>out_len</b> must be \<= DIGEST_LEN.
|
||||
* <b>out_len</b> must be \<= DIGEST256_LEN.
|
||||
*/
|
||||
void
|
||||
crypto_digest_get_digest(crypto_digest_env_t *digest,
|
||||
char *out, size_t out_len)
|
||||
{
|
||||
unsigned char r[DIGEST_LEN];
|
||||
SHA_CTX tmpctx;
|
||||
unsigned char r[DIGEST256_LEN];
|
||||
crypto_digest_env_t tmpenv;
|
||||
tor_assert(digest);
|
||||
tor_assert(out);
|
||||
/* memcpy into a temporary ctx, since SHA*_Final clears the context */
|
||||
memcpy(&tmpenv, digest, sizeof(crypto_digest_env_t));
|
||||
switch (digest->algorithm) {
|
||||
case DIGEST_SHA1:
|
||||
tor_assert(out_len <= DIGEST_LEN);
|
||||
/* memcpy into a temporary ctx, since SHA1_Final clears the context */
|
||||
memcpy(&tmpctx, &digest->d, sizeof(SHA_CTX));
|
||||
SHA1_Final(r, &tmpctx);
|
||||
SHA1_Final(r, &digest->d.sha1);
|
||||
break;
|
||||
case DIGEST_SHA256:
|
||||
tor_assert(out_len <= DIGEST256_LEN);
|
||||
SHA256_Final(r, &digest->d.sha2);
|
||||
break;
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
break;
|
||||
}
|
||||
memcpy(out, r, out_len);
|
||||
memset(r, 0, sizeof(r));
|
||||
}
|
||||
|
@ -18,6 +18,9 @@
|
||||
|
||||
/** Length of the output of our message digest. */
|
||||
#define DIGEST_LEN 20
|
||||
/** Length of the output of our second (improved) message digests. (For now
|
||||
* this is just sha256, but any it can be any other 256-byte digest). */
|
||||
#define DIGEST256_LEN 32
|
||||
/** Length of our symmetric cipher's keys. */
|
||||
#define CIPHER_KEY_LEN 16
|
||||
/** Length of our symmetric cipher's IV. */
|
||||
@ -27,9 +30,12 @@
|
||||
/** Length of our DH keys. */
|
||||
#define DH_BYTES (1024/8)
|
||||
|
||||
/** Length of a message digest when encoded in base64 with trailing = signs
|
||||
* removed. */
|
||||
/** Length of a sha1 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST_LEN 27
|
||||
/** Length of a sha256 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST256_LEN 43
|
||||
|
||||
/** Constants used to indicate no padding for public-key encryption */
|
||||
#define PK_NO_PADDING 60000
|
||||
@ -48,6 +54,13 @@
|
||||
#define FINGERPRINT_LEN 49
|
||||
/** Length of hex encoding of SHA1 digest, not including final NUL. */
|
||||
#define HEX_DIGEST_LEN 40
|
||||
/** Length of hex encoding of SHA256 digest, not including final NUL. */
|
||||
#define HEX_DIGEST256_LEN 64
|
||||
|
||||
typedef enum {
|
||||
DIGEST_SHA1,
|
||||
DIGEST_SHA256,
|
||||
} digest_algorithm_t;
|
||||
|
||||
typedef struct crypto_pk_env_t crypto_pk_env_t;
|
||||
typedef struct crypto_cipher_env_t crypto_cipher_env_t;
|
||||
@ -145,7 +158,10 @@ int crypto_cipher_decrypt_with_iv(crypto_cipher_env_t *env,
|
||||
|
||||
/* SHA-1 */
|
||||
int crypto_digest(char *digest, const char *m, size_t len);
|
||||
int crypto_digest256(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm);
|
||||
crypto_digest_env_t *crypto_new_digest_env(void);
|
||||
crypto_digest_env_t *crypto_new_digest256_env(digest_algorithm_t algorithm);
|
||||
void crypto_free_digest_env(crypto_digest_env_t *digest);
|
||||
void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
|
||||
size_t len);
|
||||
|
@ -618,14 +618,19 @@ test_crypto_sha(void)
|
||||
crypto_digest_env_t *d1 = NULL, *d2 = NULL;
|
||||
int i;
|
||||
char key[80];
|
||||
char digest[20];
|
||||
char digest[32];
|
||||
char data[50];
|
||||
char d_out1[DIGEST_LEN], d_out2[DIGEST_LEN];
|
||||
char d_out1[DIGEST_LEN], d_out2[DIGEST256_LEN];
|
||||
|
||||
/* Test SHA-1 with a test vector from the specification. */
|
||||
i = crypto_digest(data, "abc", 3);
|
||||
test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
|
||||
|
||||
/* Test SHA-256 with a test vector from the specification. */
|
||||
i = crypto_digest256(data, "abc", 3, DIGEST_SHA256);
|
||||
test_memeq_hex(data, "BA7816BF8F01CFEA414140DE5DAE2223B00361A3"
|
||||
"96177A9CB410FF61F20015AD");
|
||||
|
||||
/* Test HMAC-SHA-1 with test cases from RFC2202. */
|
||||
|
||||
/* Case 1. */
|
||||
@ -646,7 +651,7 @@ test_crypto_sha(void)
|
||||
test_streq(hex_str(digest, 20),
|
||||
"4C9007F4026250C6BC8414F9BF50C86C2D7235DA");
|
||||
|
||||
/* Case . */
|
||||
/* Case 5. */
|
||||
memset(key, 0xaa, 80);
|
||||
crypto_hmac_sha1(digest, key, 80,
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
@ -672,6 +677,27 @@ test_crypto_sha(void)
|
||||
crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
|
||||
crypto_digest(d_out2, "abcdef", 6);
|
||||
test_memeq(d_out1, d_out2, DIGEST_LEN);
|
||||
crypto_free_digest_env(d1);
|
||||
crypto_free_digest_env(d2);
|
||||
|
||||
/* Incremental digest code with sha256 */
|
||||
d1 = crypto_new_digest256_env(DIGEST_SHA256);
|
||||
test_assert(d1);
|
||||
crypto_digest_add_bytes(d1, "abcdef", 6);
|
||||
d2 = crypto_digest_dup(d1);
|
||||
test_assert(d2);
|
||||
crypto_digest_add_bytes(d2, "ghijkl", 6);
|
||||
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
|
||||
crypto_digest256(d_out2, "abcdefghijkl", 12, DIGEST_SHA256);
|
||||
test_memeq(d_out1, d_out2, DIGEST_LEN);
|
||||
crypto_digest_assign(d2, d1);
|
||||
crypto_digest_add_bytes(d2, "mno", 3);
|
||||
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
|
||||
crypto_digest256(d_out2, "abcdefmno", 9, DIGEST_SHA256);
|
||||
test_memeq(d_out1, d_out2, DIGEST_LEN);
|
||||
crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
|
||||
crypto_digest256(d_out2, "abcdef", 6, DIGEST_SHA256);
|
||||
test_memeq(d_out1, d_out2, DIGEST_LEN);
|
||||
|
||||
done:
|
||||
if (d1)
|
||||
|
Loading…
Reference in New Issue
Block a user