sha1.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha1.h"
00020 #include "crypto.h"
00021 
00022 
00034 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
00035                      const u8 *addr[], const size_t *len, u8 *mac)
00036 {
00037         unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
00038         unsigned char tk[20];
00039         const u8 *_addr[6];
00040         size_t _len[6], i;
00041 
00042         if (num_elem > 5) {
00043                 /*
00044                  * Fixed limit on the number of fragments to avoid having to
00045                  * allocate memory (which could fail).
00046                  */
00047                 return -1;
00048         }
00049 
00050         /* if key is longer than 64 bytes reset it to key = SHA1(key) */
00051         if (key_len > 64) {
00052                 if (sha1_vector(1, &key, &key_len, tk))
00053                         return -1;
00054                 key = tk;
00055                 key_len = 20;
00056         }
00057 
00058         /* the HMAC_SHA1 transform looks like:
00059          *
00060          * SHA1(K XOR opad, SHA1(K XOR ipad, text))
00061          *
00062          * where K is an n byte key
00063          * ipad is the byte 0x36 repeated 64 times
00064          * opad is the byte 0x5c repeated 64 times
00065          * and text is the data being protected */
00066 
00067         /* start out by storing key in ipad */
00068         os_memset(k_pad, 0, sizeof(k_pad));
00069         os_memcpy(k_pad, key, key_len);
00070         /* XOR key with ipad values */
00071         for (i = 0; i < 64; i++)
00072                 k_pad[i] ^= 0x36;
00073 
00074         /* perform inner SHA1 */
00075         _addr[0] = k_pad;
00076         _len[0] = 64;
00077         for (i = 0; i < num_elem; i++) {
00078                 _addr[i + 1] = addr[i];
00079                 _len[i + 1] = len[i];
00080         }
00081         if (sha1_vector(1 + num_elem, _addr, _len, mac))
00082                 return -1;
00083 
00084         os_memset(k_pad, 0, sizeof(k_pad));
00085         os_memcpy(k_pad, key, key_len);
00086         /* XOR key with opad values */
00087         for (i = 0; i < 64; i++)
00088                 k_pad[i] ^= 0x5c;
00089 
00090         /* perform outer SHA1 */
00091         _addr[0] = k_pad;
00092         _len[0] = 64;
00093         _addr[1] = mac;
00094         _len[1] = SHA1_MAC_LEN;
00095         return sha1_vector(2, _addr, _len, mac);
00096 }
00097 
00098 
00109 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
00110                u8 *mac)
00111 {
00112         return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
00113 }
00114 
00115 
00131 int sha1_prf(const u8 *key, size_t key_len, const char *label,
00132              const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
00133 {
00134         u8 counter = 0;
00135         size_t pos, plen;
00136         u8 hash[SHA1_MAC_LEN];
00137         size_t label_len = os_strlen(label) + 1;
00138         const unsigned char *addr[3];
00139         size_t len[3];
00140 
00141         addr[0] = (u8 *) label;
00142         len[0] = label_len;
00143         addr[1] = data;
00144         len[1] = data_len;
00145         addr[2] = &counter;
00146         len[2] = 1;
00147 
00148         pos = 0;
00149         while (pos < buf_len) {
00150                 plen = buf_len - pos;
00151                 if (plen >= SHA1_MAC_LEN) {
00152                         if (hmac_sha1_vector(key, key_len, 3, addr, len,
00153                                              &buf[pos]))
00154                                 return -1;
00155                         pos += SHA1_MAC_LEN;
00156                 } else {
00157                         if (hmac_sha1_vector(key, key_len, 3, addr, len,
00158                                              hash))
00159                                 return -1;
00160                         os_memcpy(&buf[pos], hash, plen);
00161                         break;
00162                 }
00163                 counter++;
00164         }
00165 
00166         return 0;
00167 }
00168 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1