diff options
Diffstat (limited to 'target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S')
-rw-r--r-- | target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S b/target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S new file mode 100644 index 000000000..963a3579a --- /dev/null +++ b/target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S @@ -0,0 +1,234 @@ +/* + * arch/ubicom32/crypto/md5_ubicom32_asm.S + * MD5 (Message Digest 5) support for Ubicom32 v3 architecture + * + * (C) Copyright 2009, Ubicom, Inc. + * + * This file is part of the Ubicom32 Linux Kernel Port. + * + * The Ubicom32 Linux Kernel Port 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. + * + * The Ubicom32 Linux Kernel Port is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Ubicom32 Linux Kernel Port. If not, + * see <http://www.gnu.org/licenses/>. + * + * Ubicom32 implementation derived from (with many thanks): + * arch/m68knommu + * arch/blackfin + * arch/parisc + */ + +#define __ASM__ +#include <asm/ip5000.h> + +#ifndef RP +#define RP A5 +#endif + +;***************************************************************************************** +; The function prototypes +;***************************************************************************************** +; void md5_ip5k_init(void) +; void md5_ip5k_transform(u32_t *data_input) +; void md5_get_digest(u32_t *digest) + +;***************************************************************************************** +; Inputs +;*****************************************************************************************; +; data_input is the pointer to the block of data over which the digest will be calculated. +; It should be word aligned. +; +; digest is the pointer to the block of data into which the digest (the output) will be written. +; It should be word aligned. +; + +;***************************************************************************************** +; Outputs +;***************************************************************************************** +; None + +;***************************************************************************************** +; An: Address Registers +;***************************************************************************************** +#define an_digest A3 +#define an_data_input A3 +#define an_security_block A4 + +;***************************************************************************************** +; Hash Constants +;***************************************************************************************** +#define HASH_MD5_IN0 0x01234567 +#define HASH_MD5_IN1 0x89abcdef +#define HASH_MD5_IN2 0xfedcba98 +#define HASH_MD5_IN3 0x76543210 + +#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2 +#define HASH_SECURITY_BLOCK_CONTROL_INIT_MD5 ((1 << 4) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION) + +;***************************************************************************************** +; Hash related defines +;***************************************************************************************** +#define hash_control 0x00(an_security_block) +#define hash_control_low 0x02(an_security_block) +#define hash_status 0x04(an_security_block) + +#define hash_input_0 0x30(an_security_block) +#define hash_input_1 0x34(an_security_block) +#define hash_input_2 0x38(an_security_block) +#define hash_input_3 0x3c(an_security_block) +#define hash_input_4 0x40(an_security_block) + +#define hash_output_0 0x70(an_security_block) +#define hash_output_0_low 0x72(an_security_block) +#define hash_output_1 0x74(an_security_block) +#define hash_output_1_low 0x76(an_security_block) +#define hash_output_2 0x78(an_security_block) +#define hash_output_2_low 0x7a(an_security_block) +#define hash_output_3 0x7c(an_security_block) +#define hash_output_3_low 0x7e(an_security_block) + +;***************************************************************************************** +; Assembly macros +;***************************************************************************************** + ; C compiler reserves RP (A5) for return address during subroutine call. + ; Use RP to return to caller +.macro call_return_macro + calli RP, 0(RP) +.endm + +#if 0 +;***************************************************************************************** +; void md5_ip5k_init(void) +; initialize the output registers of the hash module +; + ;.section .text.md5_ip5k_init,"ax",@progbits + .section .text + .global _md5_ip5k_init + .func md5_ip5k_init, _md5_ip5k_init + +_md5_ip5k_init: + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS + + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5) + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5) + + movei hash_output_0, #%hi(HASH_MD5_IN0) + movei hash_output_0_low, #%lo(HASH_MD5_IN0) + + movei hash_output_1, #%hi(HASH_MD5_IN1) + movei hash_output_1_low, #%lo(HASH_MD5_IN1) + + movei hash_output_2, #%hi(HASH_MD5_IN2) + movei hash_output_2_low, #%lo(HASH_MD5_IN2) + + movei hash_output_3, #%hi(HASH_MD5_IN3) + movei hash_output_3_low, #%lo(HASH_MD5_IN3) + + call_return_macro + .endfunc +#endif + +;***************************************************************************************** +; void md5_ip5k_init_digest(u32_t *hash_input) +; initialize the output registers of the hash module + + ;.section .text.md5_ip5k_init_digest,"ax",@progbits + .section .text + .global _md5_ip5k_init_digest + .func md5_ip5k_init_digest, _md5_ip5k_init_digest + +_md5_ip5k_init_digest: + movea an_data_input, D0 + + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS + + movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5) + movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5) + + move.4 hash_output_0, (an_data_input)4++ + move.4 hash_output_1, (an_data_input)4++ + move.4 hash_output_2, (an_data_input)4++ + move.4 hash_output_3, (an_data_input)4++ + + call_return_macro + .endfunc + +;***************************************************************************************** +; void md5_ip5k_transform(u32_t *data_input) +; performs intermediate transformation step for the hash calculation +; + ;.sect .text.md5_ip5k_transform,"ax",@progbits + .section .text + .global _md5_ip5k_transform + .func md5_ip5k_transform, _md5_ip5k_transform + +_md5_ip5k_transform: + movea an_data_input, D0 + + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS + + ; Write the first 128bits (16 bytes) + move.4 hash_input_0, (an_data_input)4++ + move.4 hash_input_1, (an_data_input)4++ + move.4 hash_input_2, (an_data_input)4++ + move.4 hash_input_3, (an_data_input)4++ + move.4 hash_input_4, D0 + + move.4 hash_input_0, (an_data_input)4++ + move.4 hash_input_1, (an_data_input)4++ + move.4 hash_input_2, (an_data_input)4++ + move.4 hash_input_3, (an_data_input)4++ + move.4 hash_input_4, D0 + + move.4 hash_input_0, (an_data_input)4++ + move.4 hash_input_1, (an_data_input)4++ + move.4 hash_input_2, (an_data_input)4++ + move.4 hash_input_3, (an_data_input)4++ + move.4 hash_input_4, D0 + + move.4 hash_input_0, (an_data_input)4++ + move.4 hash_input_1, (an_data_input)4++ + move.4 hash_input_2, (an_data_input)4++ + move.4 hash_input_3, (an_data_input)4++ + move.4 hash_input_4, D0 + + pipe_flush 0 + +md5_ip5k_transform_wait: + ; wait for the module to calculate the output hash + btst hash_status, #0 + jmpne.f md5_ip5k_transform_wait + + call_return_macro + .endfunc + +;***************************************************************************************** +; void md5_ip5k_get_digest(u32_t *digest) +; Return the hash of the input data +; + ;.sect .text.md5_get_digest,"ax",@progbits + .section .text + .global _md5_ip5k_get_digest + .func md5_ip5k_get_digest, _md5_ip5k_get_digest + +_md5_ip5k_get_digest: + movea an_digest, D0 + + moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS + + ; we have finished + move.4 0(an_digest), hash_output_0 + move.4 4(an_digest), hash_output_1 + move.4 8(an_digest), hash_output_2 + move.4 12(an_digest), hash_output_3 + + call_return_macro + .endfunc |