imxtools/sbtools: switch SHA1 implementation to Crypto++

The current implementation was custom and super slow. Since we use Crypto++
anyway, we might as well get use a good implementation.

Change-Id: I761ad7401653471e54000e1c2bc3d9882378112f
This commit is contained in:
Amaury Pouly 2017-01-03 16:09:34 +01:00
parent 8b3f5a8ad7
commit 759a78e5df
5 changed files with 28 additions and 157 deletions

View file

@ -15,7 +15,7 @@ LDFLAGS += -lcrypto++
OUTPUT = mkimxboot OUTPUT = mkimxboot
# inputs for lib # inputs for lib
IMXTOOLS_SOURCES = misc.c sb.c crypto.cpp crc.c sha1.c elf.c IMXTOOLS_SOURCES = misc.c sb.c crypto.cpp crc.c elf.c
LIBSOURCES := dualboot.c mkimxboot.c md5.c \ LIBSOURCES := dualboot.c mkimxboot.c md5.c \
$(addprefix $(IMXTOOLS_DIR),$(IMXTOOLS_SOURCES)) $(addprefix $(IMXTOOLS_DIR),$(IMXTOOLS_SOURCES))
# inputs for binary only # inputs for binary only

View file

@ -15,10 +15,10 @@ all: $(BINS)
%.o: %.cpp %.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
sbtoelf: sbtoelf.o crc.o crypto.o sha1.o xorcrypt.o dbparser.o elf.o misc.o sb.o sb1.o sbtoelf: sbtoelf.o crc.o crypto.o xorcrypt.o dbparser.o elf.o misc.o sb.o sb1.o
$(LD) -o $@ $^ $(LDFLAGS) $(LD) -o $@ $^ $(LDFLAGS)
elftosb: elftosb.o crc.o crypto.o sha1.o elf.o dbparser.o misc.o sb.o elftosb: elftosb.o crc.o crypto.o elf.o dbparser.o misc.o sb.o
$(LD) -o $@ $^ $(LDFLAGS) $(LD) -o $@ $^ $(LDFLAGS)
elftosb1: elftosb1.o xorcrypt.o elf.o misc.o sb1.o elftosb1: elftosb1.o xorcrypt.o elf.o misc.o sb1.o

View file

@ -22,6 +22,7 @@
#include "misc.h" #include "misc.h"
#include <cryptopp/modes.h> #include <cryptopp/modes.h>
#include <cryptopp/aes.h> #include <cryptopp/aes.h>
#include <cryptopp/sha.h>
using namespace CryptoPP; using namespace CryptoPP;
@ -124,3 +125,25 @@ int crypto_apply(
else else
return CRYPTO_ERROR_BADSETUP; return CRYPTO_ERROR_BADSETUP;
} }
void sha_1_init(struct sha_1_params_t *params)
{
params->object = new SHA1;
}
void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size)
{
reinterpret_cast<SHA1 *>(params->object)->Update(buffer, size);
}
void sha_1_finish(struct sha_1_params_t *params)
{
SHA1 *obj = reinterpret_cast<SHA1 *>(params->object);
obj->Final(params->hash);
delete obj;
}
void sha_1_output(struct sha_1_params_t *params, byte *out)
{
memcpy(out, params->hash, 20);
}

View file

@ -82,13 +82,11 @@ uint32_t crc_continue(uint32_t previous_crc, byte *data, int size);
/* sha1.c */ /* sha1.c */
struct sha_1_params_t struct sha_1_params_t
{ {
uint32_t hash[5]; byte hash[20]; /* final hash */
uint64_t buffer_nr_bits; void *object; /* pointer to CryptoPP::SHA1 object */
uint32_t w[80];
}; };
void sha_1_init(struct sha_1_params_t *params); void sha_1_init(struct sha_1_params_t *params);
void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data);
void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size); void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size);
void sha_1_finish(struct sha_1_params_t *params); void sha_1_finish(struct sha_1_params_t *params);
void sha_1_output(struct sha_1_params_t *params, byte *out); void sha_1_output(struct sha_1_params_t *params, byte *out);

View file

@ -1,150 +0,0 @@
/***************************************************************************
* __________ __ ___.
* 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, &params->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(&params->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;
}