diff options
Diffstat (limited to 'storage/maria/libmarias3/src/sha256.c')
-rw-r--r-- | storage/maria/libmarias3/src/sha256.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/storage/maria/libmarias3/src/sha256.c b/storage/maria/libmarias3/src/sha256.c new file mode 100644 index 00000000..8a28f906 --- /dev/null +++ b/storage/maria/libmarias3/src/sha256.c @@ -0,0 +1,131 @@ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "sha256.h" +#include "sha256_i.h" + +/** + * sha256 - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointer to the data areas + * @len: Length of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int sha256(const uint8_t *addr, const size_t len, uint8_t *mac) +{ + struct sha256_state ctx; + + sha256_init(&ctx); + + if (sha256_process(&ctx, addr, len)) + return -1; + + if (sha256_done(&ctx, mac)) + return -1; + + return 0; +} + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem, + const uint8_t *addr[], const size_t *len, uint8_t *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + const uint8_t *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) + { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return -1; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) + { + if (sha256_vector(1, &key, &key_len, tk) < 0) + return -1; + + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + memset(k_pad, 0, sizeof(k_pad)); + memcpy(k_pad, key, key_len); + + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + + for (i = 0; i < num_elem; i++) + { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + + if (sha256_vector(1 + num_elem, _addr, _len, mac) < 0) + return -1; + + memset(k_pad, 0, sizeof(k_pad)); + memcpy(k_pad, key, key_len); + + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = SHA256_MAC_LEN; + return sha256_vector(2, _addr, _len, mac); +} + + +/** + * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, + size_t data_len, uint8_t *mac) +{ + return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); +} |