From e0e61f6fdca8fbdf097d00fb58b707b88d39d0c8 Mon Sep 17 00:00:00 2001
From: Philipp Claves <pclaves@web.de>
Date: Sat, 31 Dec 2011 18:47:40 +0100
Subject: [PATCH] Fix hash head not correctly calculated on key slot init.

The buffer that was used to calculate it did not contain the current salt.
Instead of creating a new buffer, we now use the sha1 block functions directly
and hash key and salt in two calls.

Additionally a ctx2hashhead function is added to convert only the first 4 bytes
of the hash instead of converting all 20 bytes and throwing 16 bytes away afterwards.
---
 Control/keystore.c | 29 +++++------------------------
 common/sha1/sha1.c | 13 +++++++++++++
 common/sha1/sha1.h |  9 +++++++++
 3 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/Control/keystore.c b/Control/keystore.c
index c7c55b0..d068979 100644
--- a/Control/keystore.c
+++ b/Control/keystore.c
@@ -215,34 +215,15 @@ uint8_t keystore_init_slot(uint16_t index, KEY keyout){
 	if (!keystore_write_slot_status(index, KEYSLOT_USED)) return 0;
 	_delay_us(40);
 	
-	HASH fullhash;
-	sha1(&fullhash, keyout, (sizeof(KEY) + sizeof(SALT))*8);
-	memcpy(&hashes[index], fullhash, sizeof(HASH_HEAD));
+	sha1_ctx_t s;
+	sha1_init(&s);
+	sha1_nextBlock(&s, keyout);
+	sha1_lastBlock(&s, salt, sizeof(SALT));
+	sha1_ctx2hashhead(&hashes[index], &s);
 	
 	return 1;
 }
 
-/**
- * Initializes the given keyslot with an empty (all 0-bytes)
- * @param index index to the keyslot to initialize
- * @return 1 if successful, 0 if not.
- */
-uint8_t keystore_init_slot_empty(uint16_t index, KEY keyout){
-	KEY key;
-	memset(key, 0, sizeof(KEY));
-	if (!keystore_write_slot_status(index, KEYSLOT_EMPTY)) return 0;
-	_delay_us(40);
-	if (!keystore_write_key(index, key)) return 0;
-	_delay_us(40);
-	if (!keystore_write_slot_status(index, KEYSLOT_USED)) return 0;
-	_delay_us(40);
-	
-	HASH fullhash;
-	sha1(&fullhash, keyout, (sizeof(KEY) + sizeof(SALT))*8);
-	memcpy(&hashes[index], fullhash, sizeof(HASH_HEAD));
-	
-	return 1;
-}
 
 uint8_t keystore_clear_slot(uint16_t index){
 	if (!keystore_write_slot_status(index, KEYSLOT_EMPTY)) return 0;
diff --git a/common/sha1/sha1.c b/common/sha1/sha1.c
index 1b052dc..ac04bfb 100644
--- a/common/sha1/sha1.c
+++ b/common/sha1/sha1.c
@@ -231,6 +231,19 @@ void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state){
 
 /********************************************************************************************************/
 
+void sha1_ctx2hashhead (uint8_t dest[4], sha1_ctx_t *state){
+#if defined LITTLE_ENDIAN
+	((uint32_t*)dest)[0] = change_endian32(state->h[0]);
+#elif BIG_ENDIAN
+	if (dest != state->h)
+		memcpy(dest, state->h, 4);
+#else
+# error unsupported endian type!
+#endif
+}
+
+/********************************************************************************************************/
+
 uint8_t sha1_ctx_hash_compare(sha1_hash_t *ref, sha1_ctx_t *state){
 #if defined LITTLE_ENDIAN
 	uint8_t i;
diff --git a/common/sha1/sha1.h b/common/sha1/sha1.h
index ba77977..29d1a77 100644
--- a/common/sha1/sha1.h
+++ b/common/sha1/sha1.h
@@ -102,6 +102,15 @@ void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
  */ 
 void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
 
+/** \fn sha1_ctx2hashhead(uint8_t dest[4], sha1_ctx_t *state)
+ * \brief convert a state variable into a 4 byte hash value head
+ * Writes the hash value head corresponding to the state to the memory pointed by dest.
+ * \param dest pointer to the hash value destination
+ * \param state pointer to the hash context
+ */ 
+void sha1_ctx2hashhead (uint8_t dest[4], sha1_ctx_t *state);
+
+
 /** \fn sha1_ctx_hash_compare(sha1_hash_t *ref, sha1_ctx_t *state)
  * \brief compares a state variable with an actual hash value
  * \param ref sha1 hash to compere with
-- 
GitLab