From 5827937270bac874ae9e04679b3130fef9e306c4 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sun, 6 Nov 2011 01:49:13 +0000 Subject: sbtools: rename to imxtools, move imx_hid_recovery to imxtools/sbloader, fix tools to correctly handle/free memory, properly return error codes git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30907 a1c6a512-1295-4272-9138-f99709370657 --- utils/imxtools/sha1.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 utils/imxtools/sha1.c (limited to 'utils/imxtools/sha1.c') diff --git a/utils/imxtools/sha1.c b/utils/imxtools/sha1.c new file mode 100644 index 0000000000..0ad05bb5cd --- /dev/null +++ b/utils/imxtools/sha1.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +/* Based on http://en.wikipedia.org/wiki/SHA-1 */ +#include "crypto.h" + +static uint32_t rot_left(uint32_t val, int rot) +{ + return (val << rot) | (val >> (32 - rot)); +} + +static inline void byte_swapxx(byte *ptr, int size) +{ + for(int i = 0; i < size / 2; i++) + { + byte c = ptr[i]; + ptr[i] = ptr[size - i - 1]; + ptr[size - i - 1] = c; + } +} + +static void byte_swap32(uint32_t *v) +{ + byte_swapxx((byte *)v, 4); +} + +void sha_1_init(struct sha_1_params_t *params) +{ + params->hash[0] = 0x67452301; + params->hash[1] = 0xEFCDAB89; + params->hash[2] = 0x98BADCFE; + params->hash[3] = 0x10325476; + params->hash[4] = 0xC3D2E1F0; + params->buffer_nr_bits = 0; +} + +void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size) +{ + int buffer_nr_bytes = (params->buffer_nr_bits / 8) % 64; + params->buffer_nr_bits += 8 * size; + int pos = 0; + if(buffer_nr_bytes + size >= 64) + { + pos = 64 - buffer_nr_bytes; + memcpy((byte *)(params->w) + buffer_nr_bytes, buffer, 64 - buffer_nr_bytes); + sha_1_block(params, params->hash, (byte *)params->w); + for(; pos + 64 <= size; pos += 64) + sha_1_block(params, params->hash, buffer + pos); + buffer_nr_bytes = 0; + } + memcpy((byte *)(params->w) + buffer_nr_bytes, buffer + pos, size - pos); +} + +void sha_1_finish(struct sha_1_params_t *params) +{ + /* length (in bits) in big endian BEFORE preprocessing */ + byte length_big_endian[8]; + memcpy(length_big_endian, ¶ms->buffer_nr_bits, 8); + byte_swapxx(length_big_endian, 8); + /* append '1' and then '0's to the message to get 448 bit length for the last block */ + byte b = 0x80; + sha_1_update(params, &b, 1); + b = 0; + while((params->buffer_nr_bits % 512) != 448) + sha_1_update(params, &b, 1); + /* append length */ + sha_1_update(params, length_big_endian, 8); + /* go back to big endian */ + for(int i = 0; i < 5; i++) + byte_swap32(¶ms->hash[i]); +} + +void sha_1_output(struct sha_1_params_t *params, byte *out) +{ + memcpy(out, params->hash, 20); +} + +void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data) +{ + uint32_t a, b, c, d, e; + a = cur_hash[0]; + b = cur_hash[1]; + c = cur_hash[2]; + d = cur_hash[3]; + e = cur_hash[4]; + + #define w params->w + + memmove(w, data, 64); + for(int i = 0; i < 16; i++) + byte_swap32(&w[i]); + + for(int i = 16; i <= 79; i++) + w[i] = rot_left(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); + + for(int i = 0; i<= 79; i++) + { + uint32_t f, k; + if(i <= 19) + { + f = (b & c) | ((~b) & d); + k = 0x5A827999; + } + else if(i <= 39) + { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if(i <= 59) + { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else + { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = rot_left(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = rot_left(b, 30); + b = a; + a = temp; + } + #undef w + + cur_hash[0] += a; + cur_hash[1] += b; + cur_hash[2] += c; + cur_hash[3] += d; + cur_hash[4] += e; +} -- cgit v1.2.3