Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
d32033ad
Commit
d32033ad
authored
Nov 30, 2016
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
crypto/hmac_sha256: new module.
Signed-off-by:
Rusty Russell
<
rusty@rustcorp.com.au
>
parent
346058c0
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
369 additions
and
0 deletions
+369
-0
ccan/crypto/hmac_sha256/LICENSE
ccan/crypto/hmac_sha256/LICENSE
+1
-0
ccan/crypto/hmac_sha256/_info
ccan/crypto/hmac_sha256/_info
+52
-0
ccan/crypto/hmac_sha256/hmac_sha256.c
ccan/crypto/hmac_sha256/hmac_sha256.c
+132
-0
ccan/crypto/hmac_sha256/hmac_sha256.h
ccan/crypto/hmac_sha256/hmac_sha256.h
+34
-0
ccan/crypto/hmac_sha256/test/api-rfc4231.c
ccan/crypto/hmac_sha256/test/api-rfc4231.c
+150
-0
No files found.
ccan/crypto/hmac_sha256/LICENSE
0 → 120000
View file @
d32033ad
../../../licenses/BSD-MIT
\ No newline at end of file
ccan/crypto/hmac_sha256/_info
0 → 100644
View file @
d32033ad
#include "config.h"
#include <stdio.h>
#include <string.h>
/**
* crypto/hmac_sha256 - RFC2104 HMAC using SHA256.
*
* This code implements RFC2104, which is a fairly standard HMAC.
*
* License: BSD-MIT
* Maintainer: Rusty Russell <rusty@rustcorp.com.au>
*
* Example:
* #include <ccan/crypto/hmac_sha256/hmac_sha256.h>
* #include <err.h>
* #include <stdio.h>
* #include <string.h>
*
* // Simple demonstration: idential strings will have the same hash, but
* // two different strings will not.
* int main(int argc, char *argv[])
* {
* struct hmac_sha256 hash1, hash2;
*
* if (argc != 3)
* errx(1, "Usage: %s <string1> <string2>", argv[0]);
*
* hmac_sha256(&hash1, "key", 3, argv[1], strlen(argv[1]));
* hmac_sha256(&hash2, "key", 3, argv[2], strlen(argv[2]));
* printf("Hash is %s\n", memcmp(&hash1, &hash2, sizeof(hash1))
* ? "different" : "same");
* return 0;
* }
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/crypto/sha256\n");
return 0;
}
if (strcmp(argv[1], "testdepends") == 0) {
printf("ccan/str/hex\n");
return 0;
}
return 1;
}
ccan/crypto/hmac_sha256/hmac_sha256.c
0 → 100644
View file @
d32033ad
/* MIT (BSD) license - see LICENSE file for details */
#include <ccan/crypto/hmac_sha256/hmac_sha256.h>
#include <string.h>
#define IPAD 0x3636363636363636ULL
#define OPAD 0x5C5C5C5C5C5C5C5CULL
#define BLOCK_U64S (64 / sizeof(uint64_t))
static
inline
void
xor_block
(
uint64_t
block
[
BLOCK_U64S
],
uint64_t
pad
)
{
size_t
i
;
for
(
i
=
0
;
i
<
BLOCK_U64S
;
i
++
)
block
[
i
]
^=
pad
;
}
#if 1
void
hmac_sha256
(
struct
hmac_sha256
*
hmac
,
const
void
*
k
,
size_t
ksize
,
const
void
*
d
,
size_t
dsize
)
{
struct
sha256_ctx
shactx
;
uint64_t
block
[
BLOCK_U64S
];
struct
sha256
hash
,
hashed_key
;
/* (keys longer than B bytes are first hashed using H) */
if
(
ksize
>
sizeof
(
block
))
{
sha256
(
&
hashed_key
,
k
,
ksize
);
k
=
&
hashed_key
;
ksize
=
sizeof
(
hashed_key
);
}
/* From RFC2104:
*
* (1) append zeros to the end of K to create a B byte string
* (e.g., if K is of length 20 bytes and B=64, then K will be
* appended with 44 zero bytes 0x00)
*/
memcpy
(
block
,
k
,
ksize
);
memset
((
char
*
)
block
+
ksize
,
0
,
sizeof
(
block
)
-
ksize
);
/*
* (2) XOR (bitwise exclusive-OR) the B byte string computed
* in step (1) with ipad
*/
xor_block
(
block
,
IPAD
);
/*
* (3) append the stream of data 'text' to the B byte string resulting
* from step (2)
* (4) apply H to the stream generated in step (3)
*/
sha256_init
(
&
shactx
);
sha256_update
(
&
shactx
,
block
,
sizeof
(
block
));
sha256_update
(
&
shactx
,
d
,
dsize
);
sha256_done
(
&
shactx
,
&
hash
);
/*
* (5) XOR (bitwise exclusive-OR) the B byte string computed in
* step (1) with opad
*/
xor_block
(
block
,
IPAD
^
OPAD
);
/*
* (6) append the H result from step (4) to the B byte string
* resulting from step (5)
* (7) apply H to the stream generated in step (6) and output
* the result
*/
sha256_init
(
&
shactx
);
sha256_update
(
&
shactx
,
block
,
sizeof
(
block
));
sha256_update
(
&
shactx
,
&
hash
,
sizeof
(
hash
));
sha256_done
(
&
shactx
,
&
hmac
->
sha
);
}
#else
/* Direct mapping from MD5 example in RFC2104 */
void
hmac_sha256
(
struct
hmac_sha256
*
hmac
,
const
void
*
key
,
size_t
key_len
,
const
void
*
text
,
size_t
text_len
)
{
struct
sha256_ctx
context
;
unsigned
char
k_ipad
[
65
];
/* inner padding -
* key XORd with ipad
*/
unsigned
char
k_opad
[
65
];
/* outer padding -
* key XORd with opad
*//* start out by storing key in pads */
unsigned
char
tk
[
32
];
int
i
;
/* if key is longer than 64 bytes reset it to key=MD5(key) */
if
(
key_len
>
64
)
{
struct
sha256_ctx
tctx
;
sha256_init
(
&
tctx
);
sha256_update
(
&
tctx
,
key
,
key_len
);
sha256_done
(
&
tctx
,
tk
);
key
=
tk
;
key_len
=
32
;
}
bzero
(
k_ipad
,
sizeof
k_ipad
);
bzero
(
k_opad
,
sizeof
k_opad
);
bcopy
(
key
,
k_ipad
,
key_len
);
bcopy
(
key
,
k_opad
,
key_len
);
/* XOR key with ipad and opad values */
for
(
i
=
0
;
i
<
64
;
i
++
)
{
k_ipad
[
i
]
^=
0x36
;
k_opad
[
i
]
^=
0x5c
;
}
/*
* perform inner MD5
*/
sha256_init
(
&
context
);
/* init context for 1st
* pass */
sha256_update
(
&
context
,
k_ipad
,
64
);
/* start with inner pad */
sha256_update
(
&
context
,
text
,
text_len
);
/* then text of datagram */
sha256_done
(
&
context
,
&
hmac
->
sha
);
/* finish up 1st pass */
/*
* perform outer MD5
*/
sha256_init
(
&
context
);
/* init context for 2nd
* pass */
sha256_update
(
&
context
,
k_opad
,
64
);
/* start with outer pad */
sha256_update
(
&
context
,
&
hmac
->
sha
,
32
);
/* then results of 1st
* hash */
sha256_done
(
&
context
,
&
hmac
->
sha
);
/* finish up 2nd pass */
}
#endif
ccan/crypto/hmac_sha256/hmac_sha256.h
0 → 100644
View file @
d32033ad
#ifndef CCAN_CRYPTO_HMAC_SHA256_H
#define CCAN_CRYPTO_HMAC_SHA256_H
/* BSD-MIT - see LICENSE file for details */
#include "config.h"
#include <stdint.h>
#include <stdlib.h>
#include <ccan/crypto/sha256/sha256.h>
/* Uncomment this to use openssl's HMAC routines (and link with -lcrypto) */
/*#define CCAN_CRYPTO_HMAC_USE_OPENSSL 1*/
#ifdef CCAN_CRYPTO_HMAC_USE_OPENSSL
#include <openssl/hmac.h>
#endif
/**
* struct hmac_sha256 - structure representing a completed HMAC.
*/
struct
hmac_sha256
{
struct
sha256
sha
;
};
/**
* hmac_sha256 - return hmac of an object with a key.
* @hmac: the hmac to fill in
* @k: pointer to the key,
* @ksize: the number of bytes pointed to by @k
* @d: pointer to memory,
* @dsize: the number of bytes pointed to by @d
*/
void
hmac_sha256
(
struct
hmac_sha256
*
hmac
,
const
void
*
k
,
size_t
ksize
,
const
void
*
d
,
size_t
dsize
);
#endif
/* CCAN_CRYPTO_HMAC_SHA256_H */
ccan/crypto/hmac_sha256/test/api-rfc4231.c
0 → 100644
View file @
d32033ad
/* From RFC4231 "Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256,
* HMAC-SHA-384, and HMAC-SHA-512"
*
* https://tools.ietf.org/html/rfc4231
*/
#include <ccan/crypto/hmac_sha256/hmac_sha256.h>
#include <ccan/tap/tap.h>
#include <ccan/str/hex/hex.h>
#include <string.h>
#include <assert.h>
struct
test
{
const
char
*
key
,
*
data
,
*
hmac
;
};
static
struct
test
tests
[]
=
{
{
/* Test Case 1 */
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
,
/* (20 bytes) */
"4869205468657265"
,
/* ("Hi There") */
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
},
/* Test Case 2:
Test with a key shorter than the length of the HMAC output. */
{
"4a656665"
,
/* ("Jefe") */
/* ("what do ya want for nothing?") */
"7768617420646f2079612077616e7420666f72206e6f7468696e673f"
,
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
},
{
/* Test Case 3
Test with a combined length of key and data that is larger than 64
bytes (= block-size of SHA-224 and SHA-256).
*/
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
,
/* (20 bytes) */
"dddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddd"
"dddd"
,
/* (50 bytes) */
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"
},
{
/* Test Case 4
Test with a combined length of key and data that is larger than 64
bytes (= block-size of SHA-224 and SHA-256).
*/
"0102030405060708090a0b0c0d0e0f10111213141516171819"
,
/* (25 bytes) */
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcd"
,
/* (50 bytes) */
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
},
#if 0
{
/* Test Case 5
Test with a truncation of output to 128 bits.
*/
"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", /* (20 bytes) */
"546573742057697468205472756e636174696f6e", /* ("Test With Truncation") */
"a3b6167473100ee06e0c796c2955552b"
},
#endif
{
/* Test Case 6
Test with a key larger than 128 bytes (= block-size of SHA-384 and
SHA-512).
*/
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaa"
,
/* (131 bytes) */
"54657374205573696e67204c61726765"
/* ("Test Using Large") */
"72205468616e20426c6f636b2d53697a"
/* ("r Than Block-Siz") */
"65204b6579202d2048617368204b6579"
/* ("e Key - Hash Key") */
"204669727374"
,
/* (" First") */
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"
},
{
/* Test Case 7
Test with a key and data that is larger than 128 bytes (= block-size
of SHA-384 and SHA-512). */
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaa"
,
/* (131 bytes) */
"54686973206973206120746573742075"
/* ("This is a test u") */
"73696e672061206c6172676572207468"
/* ("sing a larger th") */
"616e20626c6f636b2d73697a65206b65"
/* ("an block-size ke") */
"7920616e642061206c61726765722074"
/* ("y and a larger t") */
"68616e20626c6f636b2d73697a652064"
/* ("han block-size d") */
"6174612e20546865206b6579206e6565"
/* ("ata. The key nee") */
"647320746f2062652068617368656420"
/* ("ds to be hashed ") */
"6265666f7265206265696e6720757365"
/* ("before being use") */
"642062792074686520484d414320616c"
/* ("d by the HMAC al") */
"676f726974686d2e"
,
/* ("gorithm.") */
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"
}
};
static
void
*
fromhex
(
const
char
*
str
,
size_t
*
len
)
{
void
*
p
;
*
len
=
hex_data_size
(
strlen
(
str
));
p
=
malloc
(
*
len
);
if
(
!
hex_decode
(
str
,
strlen
(
str
),
p
,
*
len
))
abort
();
return
p
;
}
int
main
(
void
)
{
size_t
i
;
struct
hmac_sha256
hmac
;
plan_tests
(
sizeof
(
tests
)
/
sizeof
(
tests
[
0
]));
for
(
i
=
0
;
i
<
sizeof
(
tests
)
/
sizeof
(
tests
[
0
]);
i
++
)
{
size_t
ksize
,
dsize
,
hmacsize
;
void
*
k
,
*
d
,
*
expect
;
k
=
fromhex
(
tests
[
i
].
key
,
&
ksize
);
d
=
fromhex
(
tests
[
i
].
data
,
&
dsize
);
expect
=
fromhex
(
tests
[
i
].
hmac
,
&
hmacsize
);
assert
(
hmacsize
==
sizeof
(
hmac
));
hmac_sha256
(
&
hmac
,
k
,
ksize
,
d
,
dsize
);
ok1
(
memcmp
(
&
hmac
,
expect
,
hmacsize
)
==
0
);
free
(
k
);
free
(
d
);
free
(
expect
);
}
return
exit_status
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment