summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-10-31 04:56:59 +0000
committerNick Mathewson <nickm@torproject.org>2007-10-31 04:56:59 +0000
commit17266cc44a0a386ec006970317e2d5941141867b (patch)
tree891f74067d3197acf270328facc1e5e13f794af4 /src/common
parent7e80640b97bbd97e8bcf5e95366f535a8bd16bfc (diff)
downloadtor-17266cc44a0a386ec006970317e2d5941141867b.tar.gz
tor-17266cc44a0a386ec006970317e2d5941141867b.zip
r16287@catbus: nickm | 2007-10-31 00:53:53 -0400
HMAC-SHA-1 implementation, with unit tests based on vectors from RVFC2202. Steven's stuff will need this. svn:r12289
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto.c50
-rw-r--r--src/common/crypto.h3
2 files changed, 52 insertions, 1 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 6c1dae9a73..8762840a54 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1261,7 +1261,7 @@ void
crypto_digest_get_digest(crypto_digest_env_t *digest,
char *out, size_t out_len)
{
- static unsigned char r[DIGEST_LEN];
+ static unsigned char r[DIGEST_LEN]; /*XXXXX020 why static? */
SHA_CTX tmpctx;
tor_assert(digest);
tor_assert(out);
@@ -1297,6 +1297,54 @@ crypto_digest_assign(crypto_digest_env_t *into,
memcpy(into,from,sizeof(crypto_digest_env_t));
}
+/**DOCDOC */
+#define DIGEST_BLOCKSIZE 64
+
+/** Compute the HMAC-SHA-1 of the <b>msg_len</b> bytes in <b>msg</b>, using
+ * the <b>key</b> of length <b>key_len</b>. Store the DIGEST_LEN-byte result
+ * in <b>hmac_out</b>.
+ */
+void
+crypto_hmac_sha1(char *hmac_out,
+ const char *key, size_t key_len,
+ const char *msg, size_t msg_len)
+{
+ SHA_CTX sha;
+ uint8_t K[DIGEST_BLOCKSIZE], D[DIGEST_LEN], K_SHORT[DIGEST_LEN];
+ const uint8_t *real_key;
+ unsigned int i;
+
+ if (key_len > DIGEST_BLOCKSIZE) {
+ SHA1((const unsigned char*)key, key_len, K_SHORT);
+ key_len = DIGEST_LEN;
+ real_key = K_SHORT;
+ } else {
+ real_key = (const uint8_t*)key;
+ }
+
+ memset(K, 0, sizeof(K));
+ memcpy(K, real_key, key_len);
+ for (i=0; i < sizeof(K); ++i)
+ K[i] ^= 0x36;
+ SHA1_Init(&sha);
+ SHA1_Update(&sha, K, sizeof(K));
+ SHA1_Update(&sha, msg, msg_len);
+ SHA1_Final(D, &sha);
+
+ /*
+ memset(K, 0, sizeof(K));
+ memcpy(K, real_key, key_len);
+ for (i=0; i < sizeof(K); ++i)
+ K[i] ^= 0x5c;
+ */
+ for (i=0; i < sizeof(K); ++i)
+ K[i] ^= (0x36 ^ 0x5c);
+ SHA1_Init(&sha);
+ SHA1_Update(&sha, K, sizeof(K));
+ SHA1_Update(&sha, D, sizeof(D));
+ SHA1_Final((unsigned char*)hmac_out, &sha);
+}
+
/* DH */
/** Shared P parameter for our DH key exchanged. */
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 09cbbe704a..610ea460d7 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -146,6 +146,9 @@ void crypto_digest_get_digest(crypto_digest_env_t *digest,
crypto_digest_env_t *crypto_digest_dup(const crypto_digest_env_t *digest);
void crypto_digest_assign(crypto_digest_env_t *into,
const crypto_digest_env_t *from);
+void crypto_hmac_sha1(char *hmac_out,
+ const char *key, size_t key_len,
+ const char *msg, size_t msg_len);
/* Key negotiation */
crypto_dh_env_t *crypto_dh_new(void);