From fa7a41a129697b6e7dce363060d2265f5fdb93a6 Mon Sep 17 00:00:00 2001
From: bg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Date: Tue, 17 Feb 2009 14:11:49 +0000
Subject: [PATCH] bug fixed in md5-asm.S ( wrong values for
 length_b%512=505..511 )

---
 md5-asm.S                | 38 ++++++++++++++++++++------------------
 md5.c                    |  3 ++-
 md5_sbox.h               |  7 +++++--
 test_src/main-md5-test.c | 21 ++++++++++++++++-----
 4 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/md5-asm.S b/md5-asm.S
index 469f9ab..de3b170 100644
--- a/md5-asm.S
+++ b/md5-asm.S
@@ -785,6 +785,7 @@ md5_lastBlock:
 	movw r16, r20 /* length_b  */ 
 	movw r14, r22 /* block_ptr */
 	movw r12, r24 /* state_ptr */
+	ldi r18, 64
 2:
 	cpi r17, 2 /* hi8(512) */	
 	brlo 2f
@@ -792,7 +793,6 @@ md5_lastBlock:
 	movw r24, r12
 	movw r22, r14
 	rcall md5_nextBlock
-	ldi r18, 64
 	add r14, r18
 	adc r15, r1
 	subi r17, 2
@@ -801,58 +801,59 @@ md5_lastBlock:
 	pop r31
 	pop r30
 
-	adiw r30, 1
+	adiw r30, 1 /* adjust Z to point to buffer */
 	movw r26, r14
 	movw r24, r16
 	adiw r24, 7
 
 	lsr r25
 	ror r24
-	lsr r24
+	lsr r25
+	ror r24
 	lsr r24 /* r24 now holds how many bytes are to copy */
-	ldi r18, 64
-	sub r18, r24
+    ldi r18, 64
+	sub r18, r24 /* r18 will hold the amount of used bytes in buffer */
 	tst r24
 4:
 	breq 5f
 	ld r0, X+
-	st Z+, r0
+	st Z+, r0 
 	dec r24
-	rjmp 4b
+	rjmp 4b /* Z points to the byte after msg in buffer */
 5:	/* append 1-bit */
 	mov r20, r16
+	ldi r19, 0x80
 	andi r20, 0x07
 	brne bit_fucking
-	ldi r19, 0x80
 	st Z+, r19
-	dec r18
+	dec r18 /* 'allocate' another byte in buffer */
 	rjmp after_bit_fucking
 bit_fucking:
-	ldi r19, 0x80
 1:
 	lsr r19
 	dec r20
 	brne 1b
 	or r0, r19
 	st -Z, r0
-	adiw r30, 1
+    adiw r30, 1
 after_bit_fucking:
 	clt	
 	cpi r18, 8
 	brmi 2f
-	set         /* store in t if the counter will also fit in this block */
+	set         /* store in t if the counter will also fit in this block (1 if fit)*/
 2:
 	tst r18
 	breq 2f
-1:
+1: /* fill remaning buffer with zeros */
 	st Z+, r1
 	dec r18
 	brne 1b
 2:
 	sbiw r30, 63
 	sbiw r30,  1
-	movw r14, r30	
+	movw r14, r30 /* r14:r15 now points to buffer */	
 	brts load_counter
+	/* counter does not fit, finalize this block */
 	movw r24, r12
 	movw r22, r14
 	rcall md5_nextBlock
@@ -864,13 +865,14 @@ after_bit_fucking:
 	brne 3b
 	
 load_counter:		
-	movw r26, r12
+	movw r26, r12 /* X points to state */
 	adiw r26, 16
 	ld r19, X+
 	ld r20, X+
 	ld r21, X+
 	ld r22, X+
-	brts post_counter_decrement	
+	brts post_counter_decrement	/* do not decremen because counter fits */
+counter_decrement:
 	subi r19, 1
 	sbci r20, 0
 	sbci r21, 0
@@ -883,8 +885,8 @@ post_counter_decrement:
 	rol r21
 	rol r22
 	rol r23
-	add r18, r16
-	adc r19, r17
+	mov r18, r16 /* r16:r17 length_b */
+	add r19, r17
 	adc r20, r1
 	adc r21, r1
 	adc r22, r1
diff --git a/md5.c b/md5.c
index ddad0b9..20ec519 100644
--- a/md5.c
+++ b/md5.c
@@ -80,7 +80,8 @@ void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_
 	uart_hexdump(&s, 1); uart_putc(' ');
 	uart_hexdump(&i, 1); uart_putc(']');
 #endif	
-	t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) + *((uint32_t*)block) + md5_T[i] ;
+	t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) 
+	    + *((uint32_t*)block) + pgm_read_dword(md5_T+i) ;
 	a[as]=a[(as+1)&3] + ROTL32(t, s);
 }
 
diff --git a/md5_sbox.h b/md5_sbox.h
index b8ab636..597b3db 100644
--- a/md5_sbox.h
+++ b/md5_sbox.h
@@ -19,7 +19,10 @@
 #ifndef MD5_SBOX_H_
 #define MD5_SBOX_H_
 
-uint32_t md5_T[]={
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+uint32_t md5_T[] PROGMEM = {
 	0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 
 	0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 
 	0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 
@@ -32,6 +35,6 @@ uint32_t md5_T[]={
 	0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 
 	0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 
 	0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 
-	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
+	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
 
 #endif /*MD5_SBOX_H_*/
diff --git a/test_src/main-md5-test.c b/test_src/main-md5-test.c
index 1ede353..90c5971 100644
--- a/test_src/main-md5-test.c
+++ b/test_src/main-md5-test.c
@@ -93,15 +93,26 @@ void testrun_md5(void){
 		"abcdefghijklmnopqrstuvwxyz", 
 		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 
 		"12345678901234567890123456789012345678901234567890123456789012345678901234567890"};
-	uint8_t i;
+	uint16_t i;
 	
 	uart_putstr("\r\n=== MD5 test suit ===");
 	for(i=0; i<7; ++i){
-		uart_putstr("\r\n MD5 (\"");
-		uart_putstr(testv[i]);
-		uart_putstr("\") = \r\n\t");
+		cli_putstr("\r\n MD5 (\"");
+		cli_putstr(testv[i]);
+		cli_putstr("\") = \r\n\t");
 		md5(&hash, testv[i], strlen(testv[i])*8);
-		uart_hexdump(hash, 16);
+		cli_hexdump(hash, 16);
+	}
+	uint8_t buffer[512/8];
+	char str[5];
+	for(i=505; i<512; ++i){
+		memset(buffer, 0, 512/8);
+		cli_putstr_P(PSTR("\r\nMD5("));
+		utoa(i, str, 10);
+		cli_putstr(str);
+		cli_putstr_P(PSTR(" zero bits) = "));
+		md5(&hash, buffer, i);
+		cli_hexdump(hash, 16);
 	}
 }
 
-- 
2.39.5