1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SHA1 hash implementation and interface functions 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/sha1.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "md5.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "crypto.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104) 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for HMAC operations 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @num_elem: Number of elements in the data vector 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @addr: Pointers to the data areas 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Lengths of the data blocks 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash (20 bytes) 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr[], const size_t *len, u8 *mac) 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char tk[20]; 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *_addr[6]; 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t _len[6], i; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (num_elem > 5) { 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Fixed limit on the number of fragments to avoid having to 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * allocate memory (which could fail). 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* if key is longer than 64 bytes reset it to key = SHA1(key) */ 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key_len > 64) { 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_vector(1, &key, &key_len, tk); 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt key = tk; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt key_len = 20; 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* the HMAC_SHA1 transform looks like: 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SHA1(K XOR opad, SHA1(K XOR ipad, text)) 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * where K is an n byte key 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * ipad is the byte 0x36 repeated 64 times 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * opad is the byte 0x5c repeated 64 times 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * and text is the data being protected */ 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* start out by storing key in ipad */ 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(k_pad, 0, sizeof(k_pad)); 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(k_pad, key, key_len); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XOR key with ipad values */ 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 64; i++) 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt k_pad[i] ^= 0x36; 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* perform inner SHA1 */ 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _addr[0] = k_pad; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _len[0] = 64; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < num_elem; i++) { 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _addr[i + 1] = addr[i]; 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _len[i + 1] = len[i]; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_vector(1 + num_elem, _addr, _len, mac); 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(k_pad, 0, sizeof(k_pad)); 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(k_pad, key, key_len); 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XOR key with opad values */ 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 64; i++) 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt k_pad[i] ^= 0x5c; 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* perform outer SHA1 */ 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _addr[0] = k_pad; 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _len[0] = 64; 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _addr[1] = mac; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _len[1] = SHA1_MAC_LEN; 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_vector(2, _addr, _len, mac); 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104) 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for HMAC operations 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data: Pointers to the data area 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data_len: Length of the data area 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash (20 bytes) 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *mac) 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for PRF 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data: Extra data to bind into the key 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data_len: Length of the data 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated pseudo-random key 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf_len: Number of bytes of key to generate 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key (e.g., PMK in IEEE 802.11i). 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_prf(const u8 *key, size_t key_len, const char *label, 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *data, size_t data_len, u8 *buf, size_t buf_len) 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 counter = 0; 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t pos, plen; 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA1_MAC_LEN]; 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t label_len = os_strlen(label) + 1; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const unsigned char *addr[3]; 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len[3]; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[0] = (u8 *) label; 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[0] = label_len; 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[1] = data; 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[1] = data_len; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[2] = &counter; 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[2] = 1; 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = 0; 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (pos < buf_len) { 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt plen = buf_len - pos; 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (plen >= SHA1_MAC_LEN) { 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(key, key_len, 3, addr, len, 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &buf[pos]); 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += SHA1_MAC_LEN; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(key, key_len, 3, addr, len, 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash); 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&buf[pos], hash, plen); 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter++; 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_T_PRF 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for PRF 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed: Seed value to bind into the key 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed_len: Length of the seed 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated pseudo-random key 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf_len: Number of bytes of key to generate 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5. 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_t_prf(const u8 *key, size_t key_len, const char *label, 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char counter = 0; 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t pos, plen; 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA1_MAC_LEN]; 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t label_len = os_strlen(label); 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 output_len[2]; 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const unsigned char *addr[5]; 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len[5]; 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[0] = hash; 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[0] = 0; 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[1] = (unsigned char *) label; 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[1] = label_len + 1; 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[2] = seed; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[2] = seed_len; 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[3] = output_len; 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[3] = 2; 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[4] = &counter; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[4] = 1; 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt output_len[0] = (buf_len >> 8) & 0xff; 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt output_len[1] = buf_len & 0xff; 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = 0; 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (pos < buf_len) { 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter++; 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt plen = buf_len - pos; 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(key, key_len, 5, addr, len, hash); 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (plen >= SHA1_MAC_LEN) { 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += SHA1_MAC_LEN; 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&buf[pos], hash, plen); 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[0] = SHA1_MAC_LEN; 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_T_PRF */ 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_TLS_PRF 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tls_prf - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246) 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @secret: Key for PRF 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @secret_len: Length of the key in bytes 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed: Seed value to bind into the key 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed_len: Length of the seed 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @out: Buffer for the generated pseudo-random key 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @outlen: Number of bytes of key to generate 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure. 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key in TLS. This PRF is defined in RFC 2246, Chapter 5. 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_prf(const u8 *secret, size_t secret_len, const char *label, 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *seed, size_t seed_len, u8 *out, size_t outlen) 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t L_S1, L_S2, i; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *S1, *S2; 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN]; 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN]; 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int MD5_pos, SHA1_pos; 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *MD5_addr[3]; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t MD5_len[3]; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const unsigned char *SHA1_addr[3]; 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t SHA1_len[3]; 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (secret_len & 1) 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_addr[0] = A_MD5; 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_len[0] = MD5_MAC_LEN; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_addr[1] = (unsigned char *) label; 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_len[1] = os_strlen(label); 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_addr[2] = seed; 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_len[2] = seed_len; 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_addr[0] = A_SHA1; 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_len[0] = SHA1_MAC_LEN; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_addr[1] = (unsigned char *) label; 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_len[1] = os_strlen(label); 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_addr[2] = seed; 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_len[2] = seed_len; 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* RFC 2246, Chapter 5 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * A(0) = seed, A(i) = HMAC(secret, A(i-1)) 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + .. 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed) 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L_S1 = L_S2 = (secret_len + 1) / 2; 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt S1 = secret; 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt S2 = secret + L_S1; 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (secret_len & 1) { 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* The last byte of S1 will be shared with S2 */ 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt S2--; 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5); 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1); 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_pos = MD5_MAC_LEN; 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_pos = SHA1_MAC_LEN; 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < outlen; i++) { 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (MD5_pos == MD5_MAC_LEN) { 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5); 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_pos = 0; 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5); 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (SHA1_pos == SHA1_MAC_LEN) { 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len, 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt P_SHA1); 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_pos = 0; 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1); 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos]; 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_pos++; 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_pos++; 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_TLS_PRF */ 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_PBKDF2 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void pbkdf2_sha1_f(const char *passphrase, const char *ssid, 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t ssid_len, int iterations, unsigned int count, 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *digest) 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN]; 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i, j; 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char count_buf[4]; 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr[2]; 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len[2]; 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t passphrase_len = os_strlen(passphrase); 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[0] = (u8 *) ssid; 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[0] = ssid_len; 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[1] = count_buf; 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[1] = 4; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* F(P, S, c, i) = U1 xor U2 xor ... Uc 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * U1 = PRF(P, S || i) 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * U2 = PRF(P, U1) 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Uc = PRF(P, Uc-1) 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count_buf[0] = (count >> 24) & 0xff; 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count_buf[1] = (count >> 16) & 0xff; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count_buf[2] = (count >> 8) & 0xff; 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count_buf[3] = count & 0xff; 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp); 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(digest, tmp, SHA1_MAC_LEN); 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 1; i < iterations; i++) { 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN, 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp2); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(tmp, tmp2, SHA1_MAC_LEN); 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (j = 0; j < SHA1_MAC_LEN; j++) 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt digest[j] ^= tmp2[j]; 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @passphrase: ASCII passphrase 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @ssid: SSID 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @ssid_len: SSID length in bytes 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iterations: Number of iterations to run 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated key 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buflen: Length of the buffer in bytes 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive PSK for WPA-PSK. For this protocol, 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * iterations is set to 4096 and buflen to 32. This function is described in 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int iterations, u8 *buf, size_t buflen) 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int count = 0; 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char *pos = buf; 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t left = buflen, plen; 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char digest[SHA1_MAC_LEN]; 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (left > 0) { 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count++; 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count, 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt digest); 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left; 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(pos, digest, plen); 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += plen; 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt left -= plen; 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */ 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef INTERNAL_SHA1 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct SHA1Context { 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 state[5]; 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 count[2]; 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char buffer[64]; 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttypedef struct SHA1Context SHA1_CTX; 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_CRYPTO_INTERNAL 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Init(struct SHA1Context *context); 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Update(struct SHA1Context *context, const void *data, u32 len); 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Final(unsigned char digest[20], struct SHA1Context *context); 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_CRYPTO_INTERNAL */ 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Transform(u32 state[5], const unsigned char buffer[64]); 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_vector - SHA-1 hash for data vector 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @num_elem: Number of elements in the data vector 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @addr: Pointers to the data areas 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Lengths of the data blocks 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *mac) 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_CTX ctx; 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Init(&ctx); 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < num_elem; i++) 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Update(&ctx, addr[i], len[i]); 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Final(mac, &ctx); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_FIPS186_2_PRF 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 xkey[64]; 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 t[5], _t[5]; 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i, j, m, k; 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *xpos = x; 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 carry; 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (seed_len > sizeof(xkey)) 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt seed_len = sizeof(xkey); 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIPS 186-2 + change notice 1 */ 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(xkey, seed, seed_len); 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(xkey + seed_len, 0, 64 - seed_len); 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[0] = 0x67452301; 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[1] = 0xEFCDAB89; 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[2] = 0x98BADCFE; 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[3] = 0x10325476; 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[4] = 0xC3D2E1F0; 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = xlen / 40; 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (j = 0; j < m; j++) { 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XSEED_j = 0 */ 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 2; i++) { 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XVAL = (XKEY + XSEED_j) mod 2^b */ 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* w_i = G(t, XVAL) */ 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(_t, t, 20); 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Transform(_t, xkey); 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[0] = host_to_be32(_t[0]); 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[1] = host_to_be32(_t[1]); 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[2] = host_to_be32(_t[2]); 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[3] = host_to_be32(_t[3]); 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[4] = host_to_be32(_t[4]); 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(xpos, _t, 20); 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XKEY = (1 + XKEY + w_i) mod 2^b */ 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry = 1; 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (k = 19; k >= 0; k--) { 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry += xkey[k] + xpos[k]; 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt xkey[k] = carry & 0xff; 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry >>= 8; 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt xpos += SHA1_MAC_LEN; 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* x_j = w_0|w_1 */ 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_FIPS186_2_PRF */ 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* ===== start - public domain SHA1 implementation ===== */ 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSHA-1 in C 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Steve Reid <sreid@sea-to-sky.net> 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt100% Public Domain 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt----------------- 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 7/98 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy James H. Brown <jbrown@burgoyne.com> 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% Public Domain 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtCorrected a problem which generated improper hash values on 16 bit machines 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtRoutine SHA1Update changed from 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtlen) 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtto 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtlong len) 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtThe 'len' parameter was declared an int which works fine on 32 bit machines. 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtHowever, on 16 bit machines an int is too small for the shifts being done 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtagainst 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtit. This caused the hash function to generate incorrect values if len was 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtgreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSince the file IO in main() reads 16K at a time, any file 8K or larger would 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"a"s). 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtI also changed the declaration of variables i & j in SHA1Update to 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtunsigned long from unsigned int for the same reason. 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtThese changes should make no difference to any 32 bit implementations since 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtan 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint and a long are the same size in those environments. 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt-- 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtI also corrected a few compiler warnings generated by Borland C. 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt1. Added #include <process.h> for exit() prototype 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt2. Removed unused variable 'j' in SHA1Final 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt3. Changed exit(0) to return(0) at end of main. 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtALL changes I made can be located by searching for comments containing 'JHB' 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt----------------- 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 8/98 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Steve Reid <sreid@sea-to-sky.net> 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% public domain 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt1- Removed #include <process.h> and used return() instead of exit() 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt----------------- 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 4/01 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Saul Kravitz <Saul.Kravitz@celera.com> 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% PD 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified to run on Compaq Alpha hardware. 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt----------------- 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 4/01 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Jouni Malinen <j@w1.fi> 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtMinor changes to match the coding style used in Dynamics. 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified September 24, 2004 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Jouni Malinen <j@w1.fi> 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtFixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined. 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt*/ 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtTest Vectors (from FIPS PUB 180-1) 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"abc" 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtA million repetitions of "a" 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt*/ 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define SHA1HANDSOFF 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* blk0() and blk() perform the initial expand. */ 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* I got the idea of expanding during the round function from SSLeay */ 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WORDS_BIGENDIAN 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \ 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (rol(block->l[i], 8) & 0x00FF00FF)) 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk0(i) block->l[i] 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \ 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R0(v,w,x,y,z,i) \ 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt w = rol(w, 30); 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R1(v,w,x,y,z,i) \ 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt w = rol(w, 30); 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R2(v,w,x,y,z,i) \ 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R3(v,w,x,y,z,i) \ 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt w = rol(w, 30); 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R4(v,w,x,y,z,i) \ 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt w=rol(w, 30); 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE /* SAK */ 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHAPrintContext(SHA1_CTX *context, char *msg) 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s (%d,%d) %x %x %x %x %x\n", 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg, 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->count[0], context->count[1], 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[0], 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[1], 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[2], 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[3], 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[4]); 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Hash a single 512-bit block. This is the core of the algorithm. */ 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Transform(u32 state[5], const unsigned char buffer[64]) 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 a, b, c, d, e; 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt typedef union { 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char c[64]; 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 l[16]; 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } CHAR64LONG16; 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CHAR64LONG16* block; 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef SHA1HANDSOFF 609dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt CHAR64LONG16 workspace; 610dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt block = &workspace; 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(block, buffer, 64); 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt block = (CHAR64LONG16 *) buffer; 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Copy context->state[] to working vars */ 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt a = state[0]; 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt b = state[1]; 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt c = state[2]; 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt d = state[3]; 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt e = state[4]; 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 4 rounds of 20 operations each. Loop unrolled. */ 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Add the working vars back into context.state[] */ 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt state[0] += a; 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt state[1] += b; 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt state[2] += c; 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt state[3] += d; 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt state[4] += e; 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Wipe variables */ 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt a = b = c = d = e = 0; 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef SHA1HANDSOFF 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(block, 0, 64); 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* SHA1Init - Initialize new context */ 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Init(SHA1_CTX* context) 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* SHA1 initialization constants */ 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[0] = 0x67452301; 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[1] = 0xEFCDAB89; 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[2] = 0x98BADCFE; 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[3] = 0x10325476; 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->state[4] = 0xC3D2E1F0; 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->count[0] = context->count[1] = 0; 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Run your data through this. */ 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Update(SHA1_CTX* context, const void *_data, u32 len) 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 i, j; 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const unsigned char *data = _data; 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHAPrintContext(context, "before"); 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt j = (context->count[0] >> 3) & 63; 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((context->count[0] += len << 3) < (len << 3)) 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->count[1]++; 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt context->count[1] += (len >> 29); 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((j + len) > 63) { 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&context->buffer[j], data, (i = 64-j)); 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Transform(context->state, context->buffer); 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for ( ; i + 63 < len; i += 64) { 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Transform(context->state, &data[i]); 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt j = 0; 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else i = 0; 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&context->buffer[j], &data[i], len - i); 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHAPrintContext(context, "after "); 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Add padding and return the message digest. */ 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Final(unsigned char digest[20], SHA1_CTX* context) 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 i; 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned char finalcount[8]; 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 8; i++) { 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt finalcount[i] = (unsigned char) 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ((context->count[(i >= 4 ? 0 : 1)] >> 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Update(context, (unsigned char *) "\200", 1); 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while ((context->count[0] & 504) != 448) { 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Update(context, (unsigned char *) "\0", 1); 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 20; i++) { 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt digest[i] = (unsigned char) 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 255); 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Wipe variables */ 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt i = 0; 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(context->buffer, 0, 64); 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(context->state, 0, 20); 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(context->count, 0, 8); 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(finalcount, 0, 8); 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* ===== end - public domain SHA1 implementation ===== */ 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* INTERNAL_SHA1 */ 734