Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
orbea
Tor
Commits
fdbb9cdf
Commit
fdbb9cdf
authored
13 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Patches
Plain Diff
Add a sha256 hmac function, with tests
parent
c0bbcf13
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/common/crypto.c
+68
-0
68 additions, 0 deletions
src/common/crypto.c
src/common/crypto.h
+3
-0
3 additions, 0 deletions
src/common/crypto.h
src/test/test_crypto.c
+70
-1
70 additions, 1 deletion
src/test/test_crypto.c
with
141 additions
and
1 deletion
src/common/crypto.c
+
68
−
0
View file @
fdbb9cdf
...
...
@@ -1740,6 +1740,74 @@ crypto_hmac_sha1(char *hmac_out,
(
unsigned
char
*
)
hmac_out
,
NULL
);
}
/** Compute the HMAC-SHA-256 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_sha256
(
char
*
hmac_out
,
const
char
*
key
,
size_t
key_len
,
const
char
*
msg
,
size_t
msg_len
)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00908000l)
/* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */
tor_assert
(
key_len
<
INT_MAX
);
tor_assert
(
msg_len
<
INT_MAX
);
HMAC
(
EVP_sha256
(),
key
,
(
int
)
key_len
,
(
unsigned
char
*
)
msg
,
(
int
)
msg_len
,
(
unsigned
char
*
)
hmac_out
,
NULL
);
#else
/* OpenSSL doesn't have an EVP implementation for SHA256. We'll need
to do HMAC on our own.
HMAC isn't so hard: To compute HMAC(key, msg):
1. If len(key) > blocksize, key = H(key).
2. If len(key) < blocksize, right-pad key up to blocksize with 0 bytes.
3. let ipad = key xor 0x363636363636....36
let opad = key xor 0x5c5c5c5c5c5c....5c
The result is H(opad | H( ipad | msg ) )
*/
#define BLOCKSIZE 64
#define DIGESTSIZE 32
uint8_t
k
[
BLOCKSIZE
];
uint8_t
pad
[
BLOCKSIZE
];
uint8_t
d
[
DIGESTSIZE
];
int
i
;
SHA256_CTX
st
;
tor_assert
(
key_len
<
INT_MAX
);
tor_assert
(
msg_len
<
INT_MAX
);
if
(
key_len
<=
BLOCKSIZE
)
{
memset
(
k
,
0
,
sizeof
(
k
));
memcpy
(
k
,
key
,
key_len
);
/* not time invariant in key_len */
}
else
{
SHA256
((
const
uint8_t
*
)
key
,
key_len
,
k
);
memset
(
k
+
DIGESTSIZE
,
0
,
sizeof
(
k
)
-
DIGESTSIZE
);
}
for
(
i
=
0
;
i
<
BLOCKSIZE
;
++
i
)
pad
[
i
]
=
k
[
i
]
^
0x36
;
SHA256_Init
(
&
st
);
SHA256_Update
(
&
st
,
pad
,
BLOCKSIZE
);
SHA256_Update
(
&
st
,
(
uint8_t
*
)
msg
,
msg_len
);
SHA256_Final
(
d
,
&
st
);
for
(
i
=
0
;
i
<
BLOCKSIZE
;
++
i
)
pad
[
i
]
=
k
[
i
]
^
0x5c
;
SHA256_Init
(
&
st
);
SHA256_Update
(
&
st
,
pad
,
BLOCKSIZE
);
SHA256_Update
(
&
st
,
d
,
DIGESTSIZE
);
SHA256_Final
((
uint8_t
*
)
hmac_out
,
&
st
);
/* Now clear everything. */
memset
(
k
,
0
,
sizeof
(
k
));
memset
(
pad
,
0
,
sizeof
(
pad
));
memset
(
d
,
0
,
sizeof
(
d
));
memset
(
&
st
,
0
,
sizeof
(
st
));
#undef BLOCKSIZE
#undef DIGESTSIZE
#endif
}
/* DH */
/** Shared P parameter for our circuit-crypto DH key exchanges. */
...
...
This diff is collapsed.
Click to expand it.
src/common/crypto.h
+
3
−
0
View file @
fdbb9cdf
...
...
@@ -196,6 +196,9 @@ void crypto_digest_assign(crypto_digest_env_t *into,
void
crypto_hmac_sha1
(
char
*
hmac_out
,
const
char
*
key
,
size_t
key_len
,
const
char
*
msg
,
size_t
msg_len
);
void
crypto_hmac_sha256
(
char
*
hmac_out
,
const
char
*
key
,
size_t
key_len
,
const
char
*
msg
,
size_t
msg_len
);
/* Key negotiation */
#define DH_TYPE_CIRCUIT 1
...
...
This diff is collapsed.
Click to expand it.
src/test/test_crypto.c
+
70
−
1
View file @
fdbb9cdf
...
...
@@ -231,7 +231,7 @@ test_crypto_sha(void)
{
crypto_digest_env_t
*
d1
=
NULL
,
*
d2
=
NULL
;
int
i
;
char
key
[
8
0
];
char
key
[
16
0
];
char
digest
[
32
];
char
data
[
50
];
char
d_out1
[
DIGEST_LEN
],
d_out2
[
DIGEST256_LEN
];
...
...
@@ -276,6 +276,75 @@ test_crypto_sha(void)
test_streq
(
hex_str
(
digest
,
20
),
"AA4AE5E15272D00E95705637CE8A3B55ED402112"
);
/* Test HMAC-SHA256 with test cases from wikipedia and RFC 4231 */
/* Case empty (wikipedia) */
crypto_hmac_sha256
(
digest
,
""
,
0
,
""
,
0
);
test_streq
(
hex_str
(
digest
,
32
),
"B613679A0814D9EC772F95D778C35FC5FF1697C493715653C6C712144292C5AD"
);
/* Case quick-brown (wikipedia) */
crypto_hmac_sha256
(
digest
,
"key"
,
3
,
"The quick brown fox jumps over the lazy dog"
,
43
);
test_streq
(
hex_str
(
digest
,
32
),
"F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8"
);
/* "Test Case 1" from RFC 4231 */
memset
(
key
,
0x0b
,
20
);
crypto_hmac_sha256
(
digest
,
key
,
20
,
"Hi There"
,
8
);
test_memeq_hex
(
digest
,
"b0344c61d8db38535ca8afceaf0bf12b"
"881dc200c9833da726e9376c2e32cff7"
);
/* "Test Case 2" from RFC 4231 */
memset
(
key
,
0x0b
,
20
);
crypto_hmac_sha256
(
digest
,
"Jefe"
,
4
,
"what do ya want for nothing?"
,
28
);
test_memeq_hex
(
digest
,
"5bdcc146bf60754e6a042426089575c7"
"5a003f089d2739839dec58b964ec3843"
);
/* "Test case 3" from RFC 4231 */
memset
(
key
,
0xaa
,
20
);
memset
(
data
,
0xdd
,
50
);
crypto_hmac_sha256
(
digest
,
key
,
20
,
data
,
50
);
test_memeq_hex
(
digest
,
"773ea91e36800e46854db8ebd09181a7"
"2959098b3ef8c122d9635514ced565fe"
);
/* "Test case 4" from RFC 4231 */
base16_decode
(
key
,
25
,
"0102030405060708090a0b0c0d0e0f10111213141516171819"
,
50
);
memset
(
data
,
0xcd
,
50
);
crypto_hmac_sha256
(
digest
,
key
,
25
,
data
,
50
);
test_memeq_hex
(
digest
,
"82558a389a443c0ea4cc819899f2083a"
"85f0faa3e578f8077a2e3ff46729665b"
);
/* "Test case 5" from RFC 4231 */
memset
(
key
,
0x0c
,
20
);
crypto_hmac_sha256
(
digest
,
key
,
20
,
"Test With Truncation"
,
20
);
test_memeq_hex
(
digest
,
"a3b6167473100ee06e0c796c2955552b"
);
/* "Test case 6" from RFC 4231 */
memset
(
key
,
0xaa
,
131
);
crypto_hmac_sha256
(
digest
,
key
,
131
,
"Test Using Larger Than Block-Size Key - Hash Key First"
,
54
);
test_memeq_hex
(
digest
,
"60e431591ee0b67f0d8a26aacbf5b77f"
"8e0bc6213728c5140546040f0ee37f54"
);
/* "Test case 7" from RFC 4231 */
memset
(
key
,
0xaa
,
131
);
crypto_hmac_sha256
(
digest
,
key
,
131
,
"This is a test using a larger than block-size key and a "
"larger than block-size data. The key needs to be hashed "
"before being used by the HMAC algorithm."
,
152
);
test_memeq_hex
(
digest
,
"9b09ffa71b942fcb27635fbcd5b0e944"
"bfdc63644f0713938a7f51535c3a35e2"
);
/* Incremental digest code. */
d1
=
crypto_new_digest_env
();
test_assert
(
d1
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment