aboutsummaryrefslogtreecommitdiffstats
path: root/modules/alg_ia32
diff options
context:
space:
mode:
Diffstat (limited to 'modules/alg_ia32')
-rw-r--r--modules/alg_ia32/asm_macr.h65
-rw-r--r--modules/alg_ia32/modinfo.txt22
-rw-r--r--modules/alg_ia32/sha160.cpp43
-rw-r--r--modules/alg_ia32/sha1core.S178
4 files changed, 308 insertions, 0 deletions
diff --git a/modules/alg_ia32/asm_macr.h b/modules/alg_ia32/asm_macr.h
new file mode 100644
index 000000000..9dfe64b43
--- /dev/null
+++ b/modules/alg_ia32/asm_macr.h
@@ -0,0 +1,65 @@
+/*************************************************
+* Assembly Macros Header File *
+* (C) 1999-2006 The Botan Project *
+*************************************************/
+
+#ifndef BOTAN_EXT_ASM_MACROS_H__
+#define BOTAN_EXT_ASM_MACROS_H__
+
+#define ALIGN .p2align 4,,15
+
+#define START_LISTING(FILENAME) \
+ .file #FILENAME; \
+ .text; \
+ .p2align 4,,15;
+
+#define FUNCTION(func_name) \
+ .align 8; \
+ ALIGN; \
+ .global func_name; \
+ .type func_name,@function; \
+func_name:
+
+#define LOOP_UNTIL(REG, NUM, LABEL) \
+ cmpl NUM, REG; \
+ jne LABEL##_LOOP
+
+#define START_LOOP(LABEL) \
+ ALIGN; \
+ LABEL##_LOOP:
+
+#define EAX %eax
+#define EBX %ebx
+#define ECX %ecx
+#define EDX %edx
+#define EBP %ebp
+#define EDI %edi
+#define ESI %esi
+#define ESP %esp
+
+#define IMM(VAL) $VAL
+
+#define PUSH(REG) pushl REG
+#define POP(REG) popl REG
+
+#define ARRAY(REG, NUM) 4*NUM(REG)
+#define ARRAY_INDIRECT(BASE, OFFSET, NUM) 4*NUM(BASE,OFFSET,4)
+#define ARG(NUM) 4*PUSHED + ARRAY(ESP, NUM)
+
+#define ASSIGN(TO, FROM) movl FROM, TO
+
+#define ADD(TO, FROM) addl FROM, TO
+#define ADD_IMM(TO, NUM) addl IMM(NUM), TO
+#define ADD2_IMM(TO, FROM, NUM) leal NUM(FROM), TO
+#define ADD3_IMM(TO, FROM, NUM) leal NUM(TO,FROM,1), TO
+
+#define XOR(TO, FROM) xorl FROM, TO
+#define AND(TO, FROM) andl FROM, TO
+#define OR(TO, FROM) orl FROM, TO
+#define ZEROIZE(REG) XOR(REG, REG)
+
+#define ROTL_IMM(REG, NUM) roll IMM(NUM), REG
+#define ROTR_IMM(REG, NUM) rorl IMM(NUM), REG
+#define BSWAP(REG) bswapl REG
+
+#endif
diff --git a/modules/alg_ia32/modinfo.txt b/modules/alg_ia32/modinfo.txt
new file mode 100644
index 000000000..e59b9f809
--- /dev/null
+++ b/modules/alg_ia32/modinfo.txt
@@ -0,0 +1,22 @@
+realname "Algorithm x86 Assembler"
+
+replace_file sha160.cpp
+add_file asm_macr.h
+add_file sha1core.S
+
+<arch>
+ia32
+</arch>
+
+<cc>
+gcc
+</cc>
+
+# ELF systems
+<os>
+linux
+freebsd
+netbsd
+openbsd
+solaris
+</os>
diff --git a/modules/alg_ia32/sha160.cpp b/modules/alg_ia32/sha160.cpp
new file mode 100644
index 000000000..d802dcec9
--- /dev/null
+++ b/modules/alg_ia32/sha160.cpp
@@ -0,0 +1,43 @@
+/*************************************************
+* SHA-160 Source File *
+* (C) 1999-2006 The Botan Project *
+*************************************************/
+
+#include <botan/sha160.h>
+#include <botan/bit_ops.h>
+
+namespace Botan {
+
+extern "C" void sha160_core(u32bit[5], const byte[64], u32bit[80]);
+
+/*************************************************
+* SHA-160 Compression Function *
+*************************************************/
+void SHA_160::hash(const byte input[])
+ {
+ sha160_core(digest, input, W);
+ }
+
+/*************************************************
+* Copy out the digest *
+*************************************************/
+void SHA_160::copy_out(byte output[])
+ {
+ for(u32bit j = 0; j != OUTPUT_LENGTH; ++j)
+ output[j] = get_byte(j % 4, digest[j/4]);
+ }
+
+/*************************************************
+* Clear memory of sensitive data *
+*************************************************/
+void SHA_160::clear() throw()
+ {
+ MDx_HashFunction::clear();
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ digest[4] = 0xC3D2E1F0;
+ }
+
+}
diff --git a/modules/alg_ia32/sha1core.S b/modules/alg_ia32/sha1core.S
new file mode 100644
index 000000000..58c536857
--- /dev/null
+++ b/modules/alg_ia32/sha1core.S
@@ -0,0 +1,178 @@
+/*************************************************
+* SHA-160 Source File *
+* (C) 1999-2006 The Botan Project *
+*************************************************/
+
+#include <botan/asm_macr.h>
+
+START_LISTING(sha1core.S)
+
+FUNCTION(sha160_core)
+ PUSH(EBP)
+ PUSH(EDI)
+ PUSH(ESI)
+ PUSH(EBX)
+
+#define PUSHED 4
+
+ ASSIGN(EBP, ARG(2))
+ ASSIGN(EDI, ARG(3))
+
+ ZEROIZE(ESI)
+
+START_LOOP(.LOAD_INPUT)
+ ADD_IMM(ESI, 4)
+
+ ASSIGN(EAX, ARRAY(EBP, 0))
+ ASSIGN(EBX, ARRAY(EBP, 1))
+ ASSIGN(ECX, ARRAY(EBP, 2))
+ ASSIGN(EDX, ARRAY(EBP, 3))
+
+ ADD_IMM(EBP, 16)
+
+ BSWAP(EAX)
+ BSWAP(EBX)
+ BSWAP(ECX)
+ BSWAP(EDX)
+
+ ASSIGN(ARRAY_INDIRECT(EDI,ESI,-4), EAX)
+ ASSIGN(ARRAY_INDIRECT(EDI,ESI,-3), EBX)
+ ASSIGN(ARRAY_INDIRECT(EDI,ESI,-2), ECX)
+ ASSIGN(ARRAY_INDIRECT(EDI,ESI,-1), EDX)
+
+LOOP_UNTIL(ESI, IMM(16), .LOAD_INPUT)
+
+ ADD2_IMM(EBP, EDI, 64)
+
+START_LOOP(.EXPANSION)
+ ADD_IMM(ESI, 4)
+
+ ZEROIZE(EAX)
+
+ ASSIGN(EBX, ARRAY(EBP, -1))
+ ASSIGN(ECX, ARRAY(EBP, -2))
+ ASSIGN(EDX, ARRAY(EBP, -3))
+
+ XOR(EAX, ARRAY(EBP, -5))
+ XOR(EBX, ARRAY(EBP, -6))
+ XOR(ECX, ARRAY(EBP, -7))
+ XOR(EDX, ARRAY(EBP, -8))
+
+ XOR(EAX, ARRAY(EBP, -11))
+ XOR(EBX, ARRAY(EBP, -12))
+ XOR(ECX, ARRAY(EBP, -13))
+ XOR(EDX, ARRAY(EBP, -14))
+
+ XOR(EAX, ARRAY(EBP, -13))
+ XOR(EBX, ARRAY(EBP, -14))
+ XOR(ECX, ARRAY(EBP, -15))
+ XOR(EDX, ARRAY(EBP, -16))
+
+ ROTL_IMM(EDX, 1)
+ ROTL_IMM(ECX, 1)
+ ROTL_IMM(EBX, 1)
+ XOR(EAX, EDX)
+ ROTL_IMM(EAX, 1)
+
+ ASSIGN(ARRAY(EBP, 0), EDX)
+ ASSIGN(ARRAY(EBP, 1), ECX)
+ ASSIGN(ARRAY(EBP, 2), EBX)
+ ASSIGN(ARRAY(EBP, 3), EAX)
+
+ ADD_IMM(EBP, 16)
+LOOP_UNTIL(ESI, IMM(80), .EXPANSION)
+
+ ASSIGN(EBP, ARG(1))
+ ASSIGN(EAX, ARRAY(EBP, 0))
+ ASSIGN(EBX, ARRAY(EBP, 1))
+ ASSIGN(ECX, ARRAY(EBP, 2))
+ ASSIGN(EDX, ARRAY(EBP, 3))
+ ASSIGN(ESI, ARRAY(EBP, 4))
+
+#define MAGIC1 0x5A827999
+#define MAGIC2 0x6ED9EBA1
+#define MAGIC3 0x8F1BBCDC
+#define MAGIC4 0xCA62C1D6
+
+#define F1(A, B, C, D, E, TEMP, MSG) \
+ ROTL_IMM(A, 5) ; \
+ ADD(E, ARRAY(EDI, MSG)) ; \
+ ASSIGN(TEMP, C) ; \
+ XOR(TEMP, D) ; \
+ AND(TEMP, B) ; \
+ XOR(TEMP, D) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, A) ; \
+ ROTR_IMM(A, 5) ; \
+ ADD3_IMM(E, TEMP, MAGIC1) ;
+
+#define F2_OR_F4(A, B, C, D, E, TEMP, MSG, MAGIC) \
+ ROTL_IMM(A, 5) ; \
+ ADD(E, ARRAY(EDI, MSG)) ; \
+ ASSIGN(TEMP, B) ; \
+ XOR(TEMP, D) ; \
+ XOR(TEMP, C) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, A) ; \
+ ROTR_IMM(A, 5) ; \
+ ADD3_IMM(E, TEMP, MAGIC) ;
+
+#define F3(A, B, C, D, E, TEMP, MSG) \
+ ROTL_IMM(A, 5) ; \
+ ADD(E, ARRAY(EDI, MSG)) ; \
+ ASSIGN(TEMP, B) ; \
+ OR(TEMP, C) ; \
+ ASSIGN(ARRAY(EDI, MSG), B) ; \
+ AND(TEMP, D) ; \
+ AND(ARRAY(EDI, MSG), C) ; \
+ OR(TEMP, ARRAY(EDI, MSG)) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, A) ; \
+ ROTR_IMM(A, 5) ; \
+ ADD3_IMM(E, TEMP, MAGIC3) ;
+
+#define F2(A, B, C, D, E, TEMP, MSG) \
+ F2_OR_F4(A, B, C, D, E, TEMP, MSG, MAGIC2)
+
+#define F4(A, B, C, D, E, TEMP, MSG) \
+ F2_OR_F4(A, B, C, D, E, TEMP, MSG, MAGIC4)
+
+#define F_BLOCK(F, MSG) \
+ F(EAX, EBX, ECX, EDX, ESI, EBP, (MSG+0)) \
+ F(ESI, EAX, EBX, ECX, EDX, EBP, (MSG+1)) \
+ F(EDX, ESI, EAX, EBX, ECX, EBP, (MSG+2)) \
+ F(ECX, EDX, ESI, EAX, EBX, EBP, (MSG+3)) \
+ F(EBX, ECX, EDX, ESI, EAX, EBP, (MSG+4))
+
+ F_BLOCK(F1, 0)
+ F_BLOCK(F1, 5)
+ F_BLOCK(F1, 10)
+ F_BLOCK(F1, 15)
+
+ F_BLOCK(F2, 20)
+ F_BLOCK(F2, 25)
+ F_BLOCK(F2, 30)
+ F_BLOCK(F2, 35)
+
+ F_BLOCK(F3, 40)
+ F_BLOCK(F3, 45)
+ F_BLOCK(F3, 50)
+ F_BLOCK(F3, 55)
+
+ F_BLOCK(F4, 60)
+ F_BLOCK(F4, 65)
+ F_BLOCK(F4, 70)
+ F_BLOCK(F4, 75)
+
+ ASSIGN(EBP, ARG(1))
+ ADD(ARRAY(EBP, 0), EAX)
+ ADD(ARRAY(EBP, 1), EBX)
+ ADD(ARRAY(EBP, 2), ECX)
+ ADD(ARRAY(EBP, 3), EDX)
+ ADD(ARRAY(EBP, 4), ESI)
+
+ POP(EBX)
+ POP(ESI)
+ POP(EDI)
+ POP(EBP)
+ ret