aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/crypto
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-08-29 17:49:23 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-29 17:49:23 -0400
commit9fd130ecbe97f3440d14d3d0c6660413e69ac532 (patch)
tree4f9c108e6a4c305e61e4d7d7044af6822741a15e /arch/sparc/crypto
parent0bdcaf7495726688a93a2f7226e9b4beaeabd2ec (diff)
sparc64: Add ctr mode support to AES driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/crypto')
-rw-r--r--arch/sparc/crypto/aes_asm.S95
-rw-r--r--arch/sparc/crypto/aes_glue.c62
2 files changed, 157 insertions, 0 deletions
diff --git a/arch/sparc/crypto/aes_asm.S b/arch/sparc/crypto/aes_asm.S
index 50faae03c592..7a975d689919 100644
--- a/arch/sparc/crypto/aes_asm.S
+++ b/arch/sparc/crypto/aes_asm.S
@@ -44,6 +44,8 @@
44 .word 0x85b02307; 44 .word 0x85b02307;
45#define MOVXTOD_O0_F0 \ 45#define MOVXTOD_O0_F0 \
46 .word 0x81b02308; 46 .word 0x81b02308;
47#define MOVXTOD_O5_F0 \
48 .word 0x81b0230d;
47#define MOVXTOD_O5_F2 \ 49#define MOVXTOD_O5_F2 \
48 .word 0x85b0230d; 50 .word 0x85b0230d;
49 51
@@ -1137,3 +1139,96 @@ ENTRY(aes_sparc64_cbc_decrypt_256)
1137 retl 1139 retl
1138 nop 1140 nop
1139ENDPROC(aes_sparc64_cbc_decrypt_256) 1141ENDPROC(aes_sparc64_cbc_decrypt_256)
1142
1143 .align 32
1144ENTRY(aes_sparc64_ctr_crypt_128)
1145 /* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */
1146 ldx [%o4 + 0x00], %g3
1147 ldx [%o4 + 0x08], %g7
1148 ldx [%o0 + 0x00], %g1
1149 ldx [%o0 + 0x08], %g2
11501: xor %g1, %g3, %o5
1151 MOVXTOD_O5_F0
1152 xor %g2, %g7, %o5
1153 MOVXTOD_O5_F2
1154 add %g7, 1, %g7
1155 add %g3, 1, %o5
1156 movrz %g7, %o5, %g3
1157 ENCRYPT_128(8, 0, 2, 4, 6)
1158 ldd [%o1 + 0x00], %f4
1159 ldd [%o1 + 0x08], %f6
1160 fxor %f4, %f0, %f4
1161 fxor %f6, %f2, %f6
1162 std %f4, [%o2 + 0x00]
1163 std %f6, [%o2 + 0x08]
1164 subcc %o3, 0x10, %o3
1165 add %o1, 0x10, %o1
1166 bne,pt %xcc, 1b
1167 add %o2, 0x10, %o2
1168 stx %g3, [%o4 + 0x00]
1169 stx %g7, [%o4 + 0x08]
1170 retl
1171 nop
1172ENDPROC(aes_sparc64_ctr_crypt_128)
1173
1174 .align 32
1175ENTRY(aes_sparc64_ctr_crypt_192)
1176 /* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */
1177 ldx [%o4 + 0x00], %g3
1178 ldx [%o4 + 0x08], %g7
1179 ldx [%o0 + 0x00], %g1
1180 ldx [%o0 + 0x08], %g2
11811: xor %g1, %g3, %o5
1182 MOVXTOD_O5_F0
1183 xor %g2, %g7, %o5
1184 MOVXTOD_O5_F2
1185 add %g7, 1, %g7
1186 add %g3, 1, %o5
1187 movrz %g7, %o5, %g3
1188 ENCRYPT_192(8, 0, 2, 4, 6)
1189 ldd [%o1 + 0x00], %f4
1190 ldd [%o1 + 0x08], %f6
1191 fxor %f4, %f0, %f4
1192 fxor %f6, %f2, %f6
1193 std %f4, [%o2 + 0x00]
1194 std %f6, [%o2 + 0x08]
1195 subcc %o3, 0x10, %o3
1196 add %o1, 0x10, %o1
1197 bne,pt %xcc, 1b
1198 add %o2, 0x10, %o2
1199 stx %g3, [%o4 + 0x00]
1200 stx %g7, [%o4 + 0x08]
1201 retl
1202 nop
1203ENDPROC(aes_sparc64_ctr_crypt_192)
1204
1205 .align 32
1206ENTRY(aes_sparc64_ctr_crypt_256)
1207 /* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */
1208 ldx [%o4 + 0x00], %g3
1209 ldx [%o4 + 0x08], %g7
1210 ldx [%o0 + 0x00], %g1
1211 ldx [%o0 + 0x08], %g2
12121: xor %g1, %g3, %o5
1213 MOVXTOD_O5_F0
1214 xor %g2, %g7, %o5
1215 MOVXTOD_O5_F2
1216 add %g7, 1, %g7
1217 add %g3, 1, %o5
1218 movrz %g7, %o5, %g3
1219 ENCRYPT_256(8, 0, 2, 4, 6)
1220 ldd [%o1 + 0x00], %f4
1221 ldd [%o1 + 0x08], %f6
1222 fxor %f4, %f0, %f4
1223 fxor %f6, %f2, %f6
1224 std %f4, [%o2 + 0x00]
1225 std %f6, [%o2 + 0x08]
1226 subcc %o3, 0x10, %o3
1227 add %o1, 0x10, %o1
1228 bne,pt %xcc, 1b
1229 add %o2, 0x10, %o2
1230 stx %g3, [%o4 + 0x00]
1231 stx %g7, [%o4 + 0x08]
1232 retl
1233 nop
1234ENDPROC(aes_sparc64_ctr_crypt_256)
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c
index 0b1de0b470a2..f457fc69edeb 100644
--- a/arch/sparc/crypto/aes_glue.c
+++ b/arch/sparc/crypto/aes_glue.c
@@ -39,6 +39,8 @@ struct aes_ops {
39 unsigned int len, u64 *iv); 39 unsigned int len, u64 *iv);
40 void (*cbc_decrypt)(const u64 *key, const u64 *input, u64 *output, 40 void (*cbc_decrypt)(const u64 *key, const u64 *input, u64 *output,
41 unsigned int len, u64 *iv); 41 unsigned int len, u64 *iv);
42 void (*ctr_crypt)(const u64 *key, const u64 *input, u64 *output,
43 unsigned int len, u64 *iv);
42}; 44};
43 45
44struct crypto_sparc64_aes_ctx { 46struct crypto_sparc64_aes_ctx {
@@ -108,6 +110,16 @@ extern void aes_sparc64_cbc_decrypt_256(const u64 *key, const u64 *input,
108 u64 *output, unsigned int len, 110 u64 *output, unsigned int len,
109 u64 *iv); 111 u64 *iv);
110 112
113extern void aes_sparc64_ctr_crypt_128(const u64 *key, const u64 *input,
114 u64 *output, unsigned int len,
115 u64 *iv);
116extern void aes_sparc64_ctr_crypt_192(const u64 *key, const u64 *input,
117 u64 *output, unsigned int len,
118 u64 *iv);
119extern void aes_sparc64_ctr_crypt_256(const u64 *key, const u64 *input,
120 u64 *output, unsigned int len,
121 u64 *iv);
122
111struct aes_ops aes128_ops = { 123struct aes_ops aes128_ops = {
112 .encrypt = aes_sparc64_encrypt_128, 124 .encrypt = aes_sparc64_encrypt_128,
113 .decrypt = aes_sparc64_decrypt_128, 125 .decrypt = aes_sparc64_decrypt_128,
@@ -117,6 +129,7 @@ struct aes_ops aes128_ops = {
117 .ecb_decrypt = aes_sparc64_ecb_decrypt_128, 129 .ecb_decrypt = aes_sparc64_ecb_decrypt_128,
118 .cbc_encrypt = aes_sparc64_cbc_encrypt_128, 130 .cbc_encrypt = aes_sparc64_cbc_encrypt_128,
119 .cbc_decrypt = aes_sparc64_cbc_decrypt_128, 131 .cbc_decrypt = aes_sparc64_cbc_decrypt_128,
132 .ctr_crypt = aes_sparc64_ctr_crypt_128,
120}; 133};
121 134
122struct aes_ops aes192_ops = { 135struct aes_ops aes192_ops = {
@@ -128,6 +141,7 @@ struct aes_ops aes192_ops = {
128 .ecb_decrypt = aes_sparc64_ecb_decrypt_192, 141 .ecb_decrypt = aes_sparc64_ecb_decrypt_192,
129 .cbc_encrypt = aes_sparc64_cbc_encrypt_192, 142 .cbc_encrypt = aes_sparc64_cbc_encrypt_192,
130 .cbc_decrypt = aes_sparc64_cbc_decrypt_192, 143 .cbc_decrypt = aes_sparc64_cbc_decrypt_192,
144 .ctr_crypt = aes_sparc64_ctr_crypt_192,
131}; 145};
132 146
133struct aes_ops aes256_ops = { 147struct aes_ops aes256_ops = {
@@ -139,6 +153,7 @@ struct aes_ops aes256_ops = {
139 .ecb_decrypt = aes_sparc64_ecb_decrypt_256, 153 .ecb_decrypt = aes_sparc64_ecb_decrypt_256,
140 .cbc_encrypt = aes_sparc64_cbc_encrypt_256, 154 .cbc_encrypt = aes_sparc64_cbc_encrypt_256,
141 .cbc_decrypt = aes_sparc64_cbc_decrypt_256, 155 .cbc_decrypt = aes_sparc64_cbc_decrypt_256,
156 .ctr_crypt = aes_sparc64_ctr_crypt_256,
142}; 157};
143 158
144extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key, 159extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key,
@@ -310,6 +325,34 @@ static int cbc_decrypt(struct blkcipher_desc *desc,
310 return err; 325 return err;
311} 326}
312 327
328static int ctr_crypt(struct blkcipher_desc *desc,
329 struct scatterlist *dst, struct scatterlist *src,
330 unsigned int nbytes)
331{
332 struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
333 struct blkcipher_walk walk;
334 int err;
335
336 blkcipher_walk_init(&walk, dst, src, nbytes);
337 err = blkcipher_walk_virt(desc, &walk);
338
339 ctx->ops->load_encrypt_keys(&ctx->key[0]);
340 while ((nbytes = walk.nbytes)) {
341 unsigned int block_len = nbytes & AES_BLOCK_MASK;
342
343 if (likely(block_len)) {
344 ctx->ops->ctr_crypt(&ctx->key[0],
345 (const u64 *)walk.src.virt.addr,
346 (u64 *) walk.dst.virt.addr,
347 block_len, (u64 *) walk.iv);
348 }
349 nbytes &= AES_BLOCK_SIZE - 1;
350 err = blkcipher_walk_done(desc, &walk, nbytes);
351 }
352 fprs_write(0);
353 return err;
354}
355
313static struct crypto_alg algs[] = { { 356static struct crypto_alg algs[] = { {
314 .cra_name = "aes", 357 .cra_name = "aes",
315 .cra_driver_name = "aes-sparc64", 358 .cra_driver_name = "aes-sparc64",
@@ -366,6 +409,25 @@ static struct crypto_alg algs[] = { {
366 .decrypt = cbc_decrypt, 409 .decrypt = cbc_decrypt,
367 }, 410 },
368 }, 411 },
412}, {
413 .cra_name = "ctr(aes)",
414 .cra_driver_name = "ctr-aes-sparc64",
415 .cra_priority = 150,
416 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
417 .cra_blocksize = AES_BLOCK_SIZE,
418 .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
419 .cra_alignmask = 7,
420 .cra_type = &crypto_blkcipher_type,
421 .cra_module = THIS_MODULE,
422 .cra_u = {
423 .blkcipher = {
424 .min_keysize = AES_MIN_KEY_SIZE,
425 .max_keysize = AES_MAX_KEY_SIZE,
426 .setkey = aes_set_key,
427 .encrypt = ctr_crypt,
428 .decrypt = ctr_crypt,
429 },
430 },
369} }; 431} };
370 432
371static bool __init sparc64_has_aes_opcode(void) 433static bool __init sparc64_has_aes_opcode(void)