hc
2024-05-08 f309769f8af08599af39b6de4f675784ce76530d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * 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 "rtw_crypto_wrap.h"
 
#include "sha256.h"
//#include "crypto.h"
#include "wlancrypto_wrap.h"
 
 
/**
 * 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 u8 *key, size_t key_len, size_t num_elem,
              const u8 *addr[], const size_t *len, u8 *mac)
{
   unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
   unsigned char tk[32];
   const u8 *_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 */
   os_memset(k_pad, 0, sizeof(k_pad));
   os_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;
 
   os_memset(k_pad, 0, sizeof(k_pad));
   os_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 u8 *key, size_t key_len, const u8 *data,
       size_t data_len, u8 *mac)
{
   return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
}