1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * SHA-256 hash implementation and interface functions 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> 4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify 6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as 7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation. 8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD 10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license. 11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details. 13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h" 16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h" 18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "sha256.h" 19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "crypto.h" 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for HMAC operations 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @num_elem: Number of elements in the data vector 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @addr: Pointers to the data areas 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Lengths of the data blocks 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash (32 bytes) 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[], const size_t *len, u8 *mac) 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned char tk[32]; 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *_addr[6]; 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t _len[6], i; 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (num_elem > 5) { 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Fixed limit on the number of fragments to avoid having to 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * allocate memory (which could fail). 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return; 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* if key is longer than 64 bytes reset it to key = SHA256(key) */ 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (key_len > 64) { 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_vector(1, &key, &key_len, tk); 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key = tk; 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key_len = 32; 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* the HMAC_SHA256 transform looks like: 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * SHA256(K XOR opad, SHA256(K XOR ipad, text)) 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * where K is an n byte key 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * ipad is the byte 0x36 repeated 64 times 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * opad is the byte 0x5c repeated 64 times 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * and text is the data being protected */ 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* start out by storing key in ipad */ 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memset(k_pad, 0, sizeof(k_pad)); 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memcpy(k_pad, key, key_len); 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* XOR key with ipad values */ 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 64; i++) 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_pad[i] ^= 0x36; 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* perform inner SHA256 */ 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _addr[0] = k_pad; 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _len[0] = 64; 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < num_elem; i++) { 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _addr[i + 1] = addr[i]; 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _len[i + 1] = len[i]; 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_vector(1 + num_elem, _addr, _len, mac); 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memset(k_pad, 0, sizeof(k_pad)); 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memcpy(k_pad, key, key_len); 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* XOR key with opad values */ 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 64; i++) 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_pad[i] ^= 0x5c; 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* perform outer SHA256 */ 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _addr[0] = k_pad; 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _len[0] = 64; 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _addr[1] = mac; 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project _len[1] = SHA256_MAC_LEN; 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_vector(2, _addr, _len, mac); 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for HMAC operations 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data: Pointers to the data area 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data_len: Length of the data area 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash (20 bytes) 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid hmac_sha256(const u8 *key, size_t key_len, const u8 *data, 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t data_len, u8 *mac) 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5A.3) 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for PRF 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @label: A unique label for each purpose of the PRF 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data: Extra data to bind into the key 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data_len: Length of the data 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buf: Buffer for the generated pseudo-random key 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buf_len: Number of bytes of key to generate 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function is used to derive new, cryptographically separate keys from a 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * given key. 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid sha256_prf(const u8 *key, size_t key_len, const char *label, 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *data, size_t data_len, u8 *buf, size_t buf_len) 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u16 counter = 0; 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t pos, plen; 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 hash[SHA256_MAC_LEN]; 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[3]; 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[3]; 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 counter_le[2]; 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = counter_le; 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = 2; 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = (u8 *) label; 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = strlen(label) + 1; 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[2] = data; 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[2] = data_len; 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = 0; 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (pos < buf_len) { 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project plen = buf_len - pos; 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_LE16(counter_le, counter); 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen >= SHA256_MAC_LEN) { 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac_sha256_vector(key, key_len, 3, addr, len, 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &buf[pos]); 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += SHA256_MAC_LEN; 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac_sha256_vector(key, key_len, 3, addr, len, hash); 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memcpy(&buf[pos], hash, plen); 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project counter++; 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef INTERNAL_SHA256 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct sha256_state { 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u64 length; 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u32 state[8], curlen; 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 buf[64]; 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void sha256_init(struct sha256_state *md); 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_process(struct sha256_state *md, const unsigned char *in, 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned long inlen); 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_done(struct sha256_state *md, unsigned char *out); 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * sha256_vector - SHA256 hash for data vector 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @num_elem: Number of elements in the data vector 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @addr: Pointers to the data areas 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Lengths of the data blocks 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *mac) 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct sha256_state ctx; 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t i; 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_init(&ctx); 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < num_elem; i++) 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_process(&ctx, addr[i], len[i]); 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_done(&ctx, mac); 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== start - public domain SHA256 implementation ===== */ 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* This is based on SHA256 implementation in LibTomCrypt that was released into 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * public domain by Tom St Denis. */ 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* the K array */ 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const unsigned long K[64] = { 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* Various logical functions */ 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define RORc(x, y) \ 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Ch(x,y,z) (z ^ (x & (y ^ z))) 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Maj(x,y,z) (((x | y) & z) | (x & y)) 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define S(x, n) RORc((x), (n)) 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef MIN 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define MIN(x, y) (((x) < (y)) ? (x) : (y)) 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* compress 512-bits */ 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_compress(struct sha256_state *md, unsigned char *buf) 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u32 S[8], W[64], t0, t1; 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u32 t; 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int i; 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* copy state into S */ 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 8; i++) { 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project S[i] = md->state[i]; 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* copy the state into 512-bits into W[0..15] */ 243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 16; i++) 244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project W[i] = WPA_GET_BE32(buf + (4 * i)); 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* fill W[16..63] */ 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 16; i < 64; i++) { 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project W[i - 16]; 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* Compress */ 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define RND(a,b,c,d,e,f,g,h,i) \ 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project t1 = Sigma0(a) + Maj(a, b, c); \ 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project d += t0; \ 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project h = t0 + t1; 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 64; ++i) { 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* feedback */ 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 8; i++) { 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[i] = md->state[i] + S[i]; 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* Initialize the hash state */ 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void sha256_init(struct sha256_state *md) 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->curlen = 0; 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->length = 0; 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[0] = 0x6A09E667UL; 279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[1] = 0xBB67AE85UL; 280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[2] = 0x3C6EF372UL; 281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[3] = 0xA54FF53AUL; 282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[4] = 0x510E527FUL; 283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[5] = 0x9B05688CUL; 284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[6] = 0x1F83D9ABUL; 285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->state[7] = 0x5BE0CD19UL; 286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project Process a block of memory though the hash 290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @param md The hash state 291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @param in The data to hash 292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @param inlen The length of the data (octets) 293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @return CRYPT_OK if successful 294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project*/ 295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_process(struct sha256_state *md, const unsigned char *in, 296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned long inlen) 297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned long n; 299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define block_size 64 300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (md->curlen > sizeof(md->buf)) 302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (inlen > 0) { 305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (md->curlen == 0 && inlen >= block_size) { 306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sha256_compress(md, (unsigned char *) in) < 0) 307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->length += block_size * 8; 309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project in += block_size; 310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project inlen -= block_size; 311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project n = MIN(inlen, (block_size - md->curlen)); 313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project memcpy(md->buf + md->curlen, in, n); 314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->curlen += n; 315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project in += n; 316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project inlen -= n; 317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (md->curlen == block_size) { 318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (sha256_compress(md, md->buf) < 0) 319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->length += 8 * block_size; 321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->curlen = 0; 322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/** 331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project Terminate the hash to get the digest 332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @param md The hash state 333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @param out [out] The destination of the hash (32 bytes) 334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project @return CRYPT_OK if successful 335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project*/ 336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_done(struct sha256_state *md, unsigned char *out) 337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int i; 339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (md->curlen >= sizeof(md->buf)) 341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* increase the length of the message */ 344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->length += md->curlen * 8; 345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* append the '1' bit */ 347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->buf[md->curlen++] = (unsigned char) 0x80; 348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* if the length is currently above 56 bytes we append zeros 350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * then compress. Then we can fall back to padding zeros and length 351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * encoding like normal. 352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (md->curlen > 56) { 354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (md->curlen < 64) { 355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->buf[md->curlen++] = (unsigned char) 0; 356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_compress(md, md->buf); 358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->curlen = 0; 359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* pad upto 56 bytes of zeroes */ 362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (md->curlen < 56) { 363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project md->buf[md->curlen++] = (unsigned char) 0; 364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* store length */ 367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE64(md->buf + 56, md->length); 368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha256_compress(md, md->buf); 369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* copy output */ 371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < 8; i++) 372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(out + (4 * i), md->state[i]); 373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== end - public domain SHA256 implementation ===== */ 378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* INTERNAL_SHA256 */ 380