summaryrefslogtreecommitdiffhomepage
path: root/src/crypto/zinc/chacha20/chacha20-mips.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/zinc/chacha20/chacha20-mips.S')
-rw-r--r--src/crypto/zinc/chacha20/chacha20-mips.S175
1 files changed, 68 insertions, 107 deletions
diff --git a/src/crypto/zinc/chacha20/chacha20-mips.S b/src/crypto/zinc/chacha20/chacha20-mips.S
index 4b8c4e6..2b82ebf 100644
--- a/src/crypto/zinc/chacha20/chacha20-mips.S
+++ b/src/crypto/zinc/chacha20/chacha20-mips.S
@@ -4,32 +4,32 @@
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
-#define MASK_U32 0x3c
-#define MASK_BYTES 0x03
-#define CHACHA20_BLOCK_SIZE 64
-#define STACK_SIZE 4*16
-
-#define X0 $t0
-#define X1 $t1
-#define X2 $t2
-#define X3 $t3
-#define X4 $t4
-#define X5 $t5
-#define X6 $t6
-#define X7 $t7
-#define X8 $v1
-#define X9 $fp
-#define X10 $s7
-#define X11 $s6
-#define X12 $s5
-#define X13 $s4
-#define X14 $s3
-#define X15 $s2
+#define MASK_U32 0x3c
+#define MASK_BYTES 0x03
+#define CHACHA20_BLOCK_SIZE 64
+#define STACK_SIZE 64
+
+#define X0 $t0
+#define X1 $t1
+#define X2 $t2
+#define X3 $t3
+#define X4 $t4
+#define X5 $t5
+#define X6 $t6
+#define X7 $t7
+#define X8 $v1
+#define X9 $fp
+#define X10 $s7
+#define X11 $s6
+#define X12 $s5
+#define X13 $s4
+#define X14 $s3
+#define X15 $s2
/* Use regs which are overwritten on exit for Tx so we don't leak clear data. */
-#define T0 $s1
-#define T1 $s0
-#define T(n) T ## n
-#define X(n) X ## n
+#define T0 $s1
+#define T1 $s0
+#define T(n) T ## n
+#define X(n) X ## n
/* Input arguments */
#define OUT $a0
@@ -37,7 +37,7 @@
#define BYTES $a2
/* KEY and NONCE argument must be u32 aligned */
#define KEY $a3
-/* NONCE pointer is given via stack */
+/* NONCE pointer is given via stack, must be u32 aligned */
#define NONCE $t9
/* Output argument */
@@ -120,23 +120,27 @@
*/
#define JMPTBL_ALIGNED(x, a, s, o) \
.Lchacha20_mips_jmptbl_aligned_ ## a: ; \
+ .set noreorder; \
.if ((s == NONCE) && (o == 0)); \
move SAVED_CA, NONCE_0; \
.else; \
lw SAVED_CA, o(s);\
.endif; \
b .Lchacha20_mips_xor_aligned_ ## x ## _b; \
- move SAVED_X, X ## a;
+ move SAVED_X, X ## a; \
+ .set reorder
#define JMPTBL_UNALIGNED(x, a, s, o) \
.Lchacha20_mips_jmptbl_unaligned_ ## a: ; \
+ .set noreorder; \
.if ((s == NONCE) && (o == 0)); \
move SAVED_CA, NONCE_0; \
.else; \
lw SAVED_CA, o(s);\
.endif; \
b .Lchacha20_mips_xor_unaligned_ ## x ## _b; \
- move SAVED_X, X ## a;
+ move SAVED_X, X ## a; \
+ .set reorder
#define AXR(A, B, C, D, K, L, M, N, V, W, Y, Z, S) \
addu X(A), X(K); \
@@ -153,20 +157,19 @@
rotl X(Z), S;
.text
-.set reorder
-.set noat
-.globl chacha20_mips
-.ent chacha20_mips
+.set reorder
+.set noat
+.globl chacha20_mips
+.ent chacha20_mips
chacha20_mips:
- .frame $sp, STACK_SIZE, $ra
+ .frame $sp, STACK_SIZE, $ra
/* This is in the fifth argument */
lw NONCE, 16($sp)
+ addiu $sp, -STACK_SIZE
+
/* Return bytes = 0. */
- .set noreorder
beqz BYTES, .Lchacha20_mips_end
- addiu $sp, -STACK_SIZE
- .set reorder
/* Calculate PTR_LAST_ROUND */
addiu PTR_LAST_ROUND, BYTES, -1
@@ -210,10 +213,9 @@ chacha20_mips:
sw T1, UNALIGNED_OFS_SP($sp)
- .set noreorder
- b .Lchacha20_rounds_start
andi BYTES, (CHACHA20_BLOCK_SIZE-1)
- .set reorder
+
+ b .Lchacha20_rounds_start
.align 4
.Loop_chacha20_rounds:
@@ -242,8 +244,9 @@ chacha20_mips:
lw X14, 8(NONCE)
lw X15, 12(NONCE)
- li $at, 9
+ li $at, 20
.Loop_chacha20_xor_rounds:
+ addiu $at, -2
AXR( 0, 1, 2, 3, 4, 5, 6, 7, 12,13,14,15, 16);
AXR( 8, 9,10,11, 12,13,14,15, 4, 5, 6, 7, 12);
AXR( 0, 1, 2, 3, 4, 5, 6, 7, 12,13,14,15, 8);
@@ -252,54 +255,45 @@ chacha20_mips:
AXR(10,11, 8, 9, 15,12,13,14, 5, 6, 7, 4, 12);
AXR( 0, 1, 2, 3, 5, 6, 7, 4, 15,12,13,14, 8);
AXR(10,11, 8, 9, 15,12,13,14, 5, 6, 7, 4, 7);
- .set noreorder
bnez $at, .Loop_chacha20_xor_rounds
- addiu $at, -1
+
+ andi $at, BYTES, MASK_U32
/* Unaligned? Jump */
bnez T1, .Loop_chacha20_unaligned
- andi $at, BYTES, MASK_U32
- /* Last round? No jump */
- bne OUT, PTR_LAST_ROUND, .Lchacha20_mips_xor_aligned_64_b
/* Load upper half of jump table addr */
lui T0, %hi(.Lchacha20_mips_jmptbl_aligned_0)
- /* Full block? Jump */
- beqz BYTES, .Lchacha20_mips_xor_aligned_64_b
+ /* Last round? No jump */
+ bne OUT, PTR_LAST_ROUND, .Lchacha20_mips_xor_aligned_64_b
+
/* Calculate lower half jump table addr and offset */
ins T0, $at, 2, 6
+ /* Full block? Jump */
+ beqz BYTES, .Lchacha20_mips_xor_aligned_64_b
+
subu T0, $at
addiu T0, %lo(.Lchacha20_mips_jmptbl_aligned_0)
-
jr T0
- /* Delay slot */
- nop
-
- .set reorder
.Loop_chacha20_unaligned:
- .set noreorder
+ /* Load upper half of jump table addr */
+ lui T0, %hi(.Lchacha20_mips_jmptbl_unaligned_0)
/* Last round? no jump */
bne OUT, PTR_LAST_ROUND, .Lchacha20_mips_xor_unaligned_64_b
- /* Load upper half of jump table addr */
- lui T0, %hi(.Lchacha20_mips_jmptbl_unaligned_0)
+
+ /* Calculate lower half jump table addr and offset */
+ ins T0, $at, 2, 6
/* Full block? Jump */
beqz BYTES, .Lchacha20_mips_xor_unaligned_64_b
- /* Calculate lower half jump table addr and offset */
- ins T0, $at, 2, 6
subu T0, $at
addiu T0, %lo(.Lchacha20_mips_jmptbl_unaligned_0)
-
jr T0
- /* Delay slot */
- nop
-
- .set reorder
/* Aligned code path
*/
@@ -319,23 +313,13 @@ chacha20_mips:
STORE_ALIGNED(16, 3, $sp, 12+CONSTANT_OFS_SP)
STORE_ALIGNED(12, 2, $sp, 8+CONSTANT_OFS_SP)
STORE_ALIGNED( 8, 1, $sp, 4+CONSTANT_OFS_SP)
-.Lchacha20_mips_xor_aligned_4_b:
- /* STORE_ALIGNED( 4, 0, $sp, 0+CONSTANT_OFS_SP) */
- lw T0, 0+CONSTANT_OFS_SP($sp)
- lw T1, 0(IN)
- addu X0, T0
- CPU_TO_LE32(X0)
- xor X0, T1
- .set noreorder
+ STORE_ALIGNED( 4, 0, $sp, 0+CONSTANT_OFS_SP)
+
bne OUT, PTR_LAST_ROUND, .Loop_chacha20_rounds
- sw X0, 0(OUT)
- .set reorder
- .set noreorder
- bne $at, BYTES, .Lchacha20_mips_xor_bytes
- /* Empty delayslot, Increase NONCE_0, return NONCE_0 value */
+ /* Increase NONCE_0, return NONCE_0 value */
addiu NONCE_0, 1
- .set reorder
+ bne $at, BYTES, .Lchacha20_mips_xor_bytes
.Lchacha20_mips_xor_done:
/* Restore used registers */
@@ -350,12 +334,9 @@ chacha20_mips:
lw $s6, 32($sp)
lw $s7, 36($sp)
.Lchacha20_mips_end:
- .set noreorder
- jr $ra
addiu $sp, STACK_SIZE
- .set reorder
+ jr $ra
- .set noreorder
/* Start jump table */
JMPTBL_ALIGNED( 0, 0, $sp, 0+CONSTANT_OFS_SP)
JMPTBL_ALIGNED( 4, 1, $sp, 4+CONSTANT_OFS_SP)
@@ -374,7 +355,6 @@ chacha20_mips:
JMPTBL_ALIGNED(56, 14, NONCE, 8)
JMPTBL_ALIGNED(60, 15, NONCE,12)
/* End jump table */
- .set reorder
/* Unaligned code path
*/
@@ -393,28 +373,18 @@ chacha20_mips:
STORE_UNALIGNED(16, 3, $sp, 12+CONSTANT_OFS_SP)
STORE_UNALIGNED(12, 2, $sp, 8+CONSTANT_OFS_SP)
STORE_UNALIGNED( 8, 1, $sp, 4+CONSTANT_OFS_SP)
-.Lchacha20_mips_xor_unaligned_4_b:
- /* STORE_UNALIGNED( 4, 0, $sp, 0+CONSTANT_OFS_SP) */
- lw T0, 0+CONSTANT_OFS_SP($sp)
- lwl T1, 0+MSB(IN)
- lwr T1, 0+LSB(IN)
- addu X0, T0
- CPU_TO_LE32(X0)
- xor X0, T1
- swl X0, 0+MSB(OUT)
- .set noreorder
+ STORE_UNALIGNED( 4, 0, $sp, 0+CONSTANT_OFS_SP)
+
bne OUT, PTR_LAST_ROUND, .Loop_chacha20_rounds
- swr X0, 0+LSB(OUT)
- .set reorder
/* Fall through to byte handling */
- .set noreorder
+ .set noreorder
beq $at, BYTES, .Lchacha20_mips_xor_done
/* Empty delayslot, increase NONCE_0, return NONCE_0 value */
.Lchacha20_mips_xor_unaligned_0_b:
.Lchacha20_mips_xor_aligned_0_b:
addiu NONCE_0, 1
- .set reorder
+ .set reorder
.Lchacha20_mips_xor_bytes:
addu OUT, $at
@@ -426,28 +396,21 @@ chacha20_mips:
CPU_TO_LE32(SAVED_X)
ROTR(SAVED_X)
xor T1, SAVED_X
- .set noreorder
- beqz $at, .Lchacha20_mips_xor_done
sb T1, 0(OUT)
- .set reorder
+ beqz $at, .Lchacha20_mips_xor_done
/* Second byte */
lbu T1, 1(IN)
andi $at, BYTES, 1
ROTx SAVED_X, 8
xor T1, SAVED_X
- .set noreorder
- beqz $at, .Lchacha20_mips_xor_done
sb T1, 1(OUT)
- .set reorder
+ beqz $at, .Lchacha20_mips_xor_done
/* Third byte */
lbu T1, 2(IN)
ROTx SAVED_X, 8
xor T1, SAVED_X
- .set noreorder
- b .Lchacha20_mips_xor_done
sb T1, 2(OUT)
- .set reorder
-.set noreorder
+ b .Lchacha20_mips_xor_done
.Lchacha20_mips_jmptbl_unaligned:
/* Start jump table */
@@ -468,7 +431,5 @@ chacha20_mips:
JMPTBL_UNALIGNED(56, 14, NONCE, 8)
JMPTBL_UNALIGNED(60, 15, NONCE,12)
/* End jump table */
-.set reorder
-
.end chacha20_mips
.set at