From a51977684709a269b0d3a1b127d6b1a90d60c391 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 29 Jun 2017 16:54:49 -0500 Subject: [PATCH] Add implementation of the basic block-processing function for SHA-1. --- sha1.asm | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sha1.h | 11 +++ sha1.macros | 132 +++++++++++++++++++++++++ sha1test.c | 30 ++++++ 4 files changed, 453 insertions(+) create mode 100644 sha1.asm create mode 100644 sha1.h create mode 100644 sha1.macros create mode 100644 sha1test.c diff --git a/sha1.asm b/sha1.asm new file mode 100644 index 0000000..aa1b846 --- /dev/null +++ b/sha1.asm @@ -0,0 +1,280 @@ + case on + mcopy sha1.macros + mcopy rotate.macros + +* Direct page locations +;chunk gequ 0 ; 8 bytes +a_ gequ 8 ; elements of state +b gequ 12 +c gequ 16 +d gequ 20 +e gequ 24 +f gequ 28 ; result of function in hash computation +k gequ 32 +temp gequ 36 +h0 gequ 40 +h1 gequ 44 +h2 gequ 48 +h3 gequ 52 +h4 gequ 56 +w gequ 60 + +initial_value privdata + dc h'67452301 efcdab89 98badcfe 10325476 c3d2e1f0' + end + + +sha1_init start + CFunction SHA1_INIT + end + +SHA1_INIT start + lda #$2301 + sta h0 + lda #$6745 + sta h0+2 + + lda #$AB89 + sta h1 + lda #$EFCD + sta h1+2 + + lda #$DCFE + sta h2 + lda #$98BA + sta h2+2 + + lda #$5476 + sta h3 + lda #$1032 + sta h3+2 + + lda #$E1F0 + sta h4 + lda #$C3D2 + sta h4+2 + rtl + end + + +sha1_processchunk start + CFunction SHA1_PROCESSCHUNK + end + +SHA1_PROCESSCHUNK start + + ComputeSchedule + + lda h0 + sta a_ + lda h0+2 + sta a_+2 + + lda h1 + sta b + lda h1+2 + sta b+2 + + lda h2 + sta c + lda h2+2 + sta c+2 + + lda h3 + sta d + lda h3+2 + sta d+2 + + lda h4 + sta e + lda h4+2 + sta e+2 + + ldy #0 +loop cpy #60 + bge f_60 + cpy #40 + bge f_40 + cpy #20 + bge f_20 + +* f_0 to f_19 +f_0 lda c + eor d + and b + eor d + sta f + lda #$7999 + sta k + + lda c+2 + eor d+2 + and b+2 + eor d+2 + sta f+2 + lda #$5A82 + sta k+2 + bra after_f + +* f_20 to f_39 +f_20 lda b + eor c + eor d + sta f + lda #$EBA1 + sta k + + lda b+2 + eor c+2 + eor d+2 + sta f+2 + lda #$6ED9 + sta k+2 + bra after_f + +* f_40 to f_59 +f_40 lda c + ora d + and b + sta temp + lda c + and d + ora temp + sta f + lda #$BCDC + sta k + + lda c+2 + ora d+2 + and b+2 + sta temp + lda c+2 + and d+2 + ora temp + sta f+2 + lda #$8F1B + sta k+2 + bra after_f + +* f_60 to f_79 +f_60 lda b + eor c + eor d + sta f + lda #$C1D6 + sta k + + lda b+2 + eor c+2 + eor d+2 + sta f+2 + lda #$CA62 + sta k+2 + bra after_f + +after_f anop + ROTL4MOVE temp,a_,5 + phy + tya + asl a + asl a + tax + clc + lda w,x + adc temp + tay + lda w+2,x + adc temp+2 + tax + clc + tya + adc f + tay + txa + adc f+2 + tax + clc + tya + adc e + tay + txa + adc e+2 + tax + clc + tya + adc k + sta temp + txa + adc k+2 + sta temp+2 + ply + + lda d + sta e + lda d+2 + sta e+2 + + lda c + sta d + lda c+2 + sta d+2 + + ROTL4MOVE c,b,30 + + lda a_ + sta b + lda a_+2 + sta b+2 + + lda temp + sta a_ + lda temp+2 + sta a_+2 + + iny + cpy #80 + bge endloop + jmp loop + +endloop clc + lda h0 + adc a_ + sta h0 + lda h0+2 + adc a_+2 + sta h0+2 + + clc + lda h1 + adc b + sta h1 + lda h1+2 + adc b+2 + sta h1+2 + + clc + lda h2 + adc c + sta h2 + lda h2+2 + adc c+2 + sta h2+2 + + clc + lda h3 + adc d + sta h3 + lda h3+2 + adc d+2 + sta h3+2 + + clc + lda h4 + adc e + sta h4 + lda h4+2 + adc e+2 + sta h4+2 + + rtl + end diff --git a/sha1.h b/sha1.h new file mode 100644 index 0000000..dcf0481 --- /dev/null +++ b/sha1.h @@ -0,0 +1,11 @@ +struct sha1_context { + unsigned char reserved1[8]; + unsigned long a,b,c,d,e; + unsigned char reserved2[12]; + unsigned long h0,h1,h2,h3,h4; + unsigned char chunk[64]; + unsigned char reserved3[300]; +}; + +int sha1_init(struct sha1_context *context); +int sha1_processchunk(struct sha1_context *context); diff --git a/sha1.macros b/sha1.macros new file mode 100644 index 0000000..6fe9cb2 --- /dev/null +++ b/sha1.macros @@ -0,0 +1,132 @@ +* This makes a function wrapper that is callable from C, +* taking a pointer to the context structure as its argument. + macro + CFunction &fn + phb + plx + ply + tdc + pld + plb + plb + phy + phx + plb + pha + jsl &fn + pld + rtl + mend + + +* Macros to operate on elements of the message schedule (W) + macro +&lab lda_w &i,&inc + aif C:&inc<>0,.haveinc + lcla &inc +.haveinc + aif w+(&i)*4+&inc>255,.bigidx +&lab lda w+(&i)*4+&inc + ago .end +.bigidx +&lab ldx #((&i)-16)*4+&inc + lda w+16*4,x +.end + mend + + macro +&lab eor_w &i,&inc + aif C:&inc<>0,.haveinc + lcla &inc +.haveinc + aif w+(&i)*4+&inc>255,.bigidx +&lab eor w+(&i)*4+&inc + ago .end +.bigidx +&lab ldx #((&i)-16)*4+&inc + eor w+16*4,x +.end + mend + + macro +&lab sta_w &i,&inc + aif C:&inc<>0,.haveinc + lcla &inc +.haveinc + aif w+(&i)*4+&inc>255,.bigidx +&lab sta w+(&i)*4+&inc + ago .end +.bigidx +&lab ldx #((&i)-16)*4+&inc + sta w+16*4,x +.end + mend + + macro +&lab inc_w &i,&inc + aif C:&inc<>0,.haveinc + lcla &inc +.haveinc + aif w+(&i)*4+&inc>255,.bigidx +&lab inc w+(&i)*4+&inc + ago .end +.bigidx +&lab ldx #((&i)-16)*4+&inc + inc w+16*4,x +.end + mend + + macro +&lab rol_w &i,&inc + aif C:&inc<>0,.haveinc + lcla &inc +.haveinc + aif w+(&i)*4+&inc>255,.bigidx +&lab rol w+(&i)*4+&inc + ago .end +.bigidx +&lab ldx #((&i)-16)*4+&inc + rol w+16*4,x +.end + mend + + +* Compute the message schedule (W_0 to W_79) + macro + ComputeSchedule + lcla &i + +; Flip the endianness of W_0 to W_15 (the current chunk of the message) +.loop1 + lda w+&i*4 + xba + ldx w+&i*4+2 + sta w+&i*4+2 + txa + xba + sta w+&i*4 +&i seta &i+1 + aif &i<16,.loop1 + +; compute the rest of the message schedule (W_16 to W_79) +.loop2 + lda_w &i-3 + eor_w &i-8 + eor_w &i-14 + eor_w &i-16 + sta_w &i + asl a ; to set carry + + lda_w &i-3,2 + eor_w &i-8,2 + eor_w &i-14,2 + eor_w &i-16,2 + rol a + sta_w &i,2 + + rol_w &i + +&i seta &i+1 + aif &i<80,.loop2 + mend + diff --git a/sha1test.c b/sha1test.c new file mode 100644 index 0000000..37b338e --- /dev/null +++ b/sha1test.c @@ -0,0 +1,30 @@ +#include "sha1.h" +#include + +int main(void) { + struct sha1_context context = {{0}, 0,0,0,0,0, {0}, 0,0,0,0,0, + {0x61,0x62,0x63,0x80, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x18 + }, + {0}}; + + sha1_init(&context); + sha1_processchunk(&context); + + printf("abcde = %08lx %08lx %08lx %08lx %08lx\n", context.a, context.b, context.c, context.d, context.e); + printf("h[..] = %08lx %08lx %08lx %08lx %08lx\n", context.h0, context.h1, context.h2, context.h3, context.h4); +}