2 * linux/arch/arm/lib/sha1.S
4 * SHA transform optimized for ARM
6 * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
7 * Created: September 17, 2005
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * The reference implementation for this code is linux/lib/sha1.c
16 #include <linux/linkage.h>
22 * void sha_transform(__u32 *digest, const char *in, __u32 *W)
24 * Note: the "in" ptr may be unaligned.
29 stmfd sp!, {r4 - r8, lr}
31 @ for (i = 0; i < 16; i++)
32 @ W[i] = be32_to_cpu(in[i]);
49 orr r5, r5, r4, lsl #8
50 orr r6, r6, r5, lsl #8
51 orr r7, r7, r6, lsl #8
56 @ for (i = 0; i < 64; i++)
57 @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
74 * The SHA functions are:
76 * f1(B,C,D) = (D ^ (B & (C ^ D)))
77 * f2(B,C,D) = (B ^ C ^ D)
78 * f3(B,C,D) = ((B & C) | (D & (B | C)))
80 * Then the sub-blocks are processed as follows:
82 * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
88 * We therefore unroll each loop 5 times to avoid register shuffling.
89 * Also the ror for C (and also D and E which are successivelyderived
90 * from it) is applied in place to cut on an additional mov insn for
94 .macro sha_f1, A, B, C, D, E
97 add \E, r1, \E, ror #2
98 and ip, \B, ip, ror #2
99 add \E, \E, \A, ror #27
100 eor ip, ip, \D, ror #2
105 .macro sha_f2, A, B, C, D, E
107 add \E, r1, \E, ror #2
108 eor ip, \B, \C, ror #2
109 add \E, \E, \A, ror #27
110 eor ip, ip, \D, ror #2
115 .macro sha_f3, A, B, C, D, E
117 add \E, r1, \E, ror #2
118 orr ip, \B, \C, ror #2
119 add \E, \E, \A, ror #27
120 and ip, ip, \D, ror #2
122 and r3, \B, \C, ror #2
132 /* adjust initial values */
138 sha_f1 r4, r5, r6, r7, r8
139 sha_f1 r8, r4, r5, r6, r7
140 sha_f1 r7, r8, r4, r5, r6
141 sha_f1 r6, r7, r8, r4, r5
142 sha_f1 r5, r6, r7, r8, r4
149 sha_f2 r4, r5, r6, r7, r8
150 sha_f2 r8, r4, r5, r6, r7
151 sha_f2 r7, r8, r4, r5, r6
152 sha_f2 r6, r7, r8, r4, r5
153 sha_f2 r5, r6, r7, r8, r4
160 sha_f3 r4, r5, r6, r7, r8
161 sha_f3 r8, r4, r5, r6, r7
162 sha_f3 r7, r8, r4, r5, r6
163 sha_f3 r6, r7, r8, r4, r5
164 sha_f3 r5, r6, r7, r8, r4
167 ldr r1, .L_sha_K + 12
171 sha_f2 r4, r5, r6, r7, r8
172 sha_f2 r8, r4, r5, r6, r7
173 sha_f2 r7, r8, r4, r5, r6
174 sha_f2 r6, r7, r8, r4, r5
175 sha_f2 r5, r6, r7, r8, r4
178 ldmia r0, {r1, r2, r3, ip, lr}
181 add r6, r3, r6, ror #2
182 add r7, ip, r7, ror #2
183 add r8, lr, r8, ror #2
186 ldmfd sp!, {r4 - r8, pc}
188 ENDPROC(sha_transform)
191 .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
195 * void sha_init(__u32 *buf)
198 .L_sha_initial_digest:
199 .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
204 adr r1, .L_sha_initial_digest
205 ldmia r1, {r1, r2, r3, ip, lr}
206 stmia r0, {r1, r2, r3, ip, lr}