aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/pcbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/pcbc.c')
-rw-r--r--crypto/pcbc.c105
1 files changed, 24 insertions, 81 deletions
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index c3ed8a1c9f46..fe704775f88f 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -24,7 +24,6 @@
24 24
25struct crypto_pcbc_ctx { 25struct crypto_pcbc_ctx {
26 struct crypto_cipher *child; 26 struct crypto_cipher *child;
27 void (*xor)(u8 *dst, const u8 *src, unsigned int bs);
28}; 27};
29 28
30static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key, 29static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key,
@@ -45,9 +44,7 @@ static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key,
45 44
46static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc, 45static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
47 struct blkcipher_walk *walk, 46 struct blkcipher_walk *walk,
48 struct crypto_cipher *tfm, 47 struct crypto_cipher *tfm)
49 void (*xor)(u8 *, const u8 *,
50 unsigned int))
51{ 48{
52 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 49 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
53 crypto_cipher_alg(tfm)->cia_encrypt; 50 crypto_cipher_alg(tfm)->cia_encrypt;
@@ -58,10 +55,10 @@ static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
58 u8 *iv = walk->iv; 55 u8 *iv = walk->iv;
59 56
60 do { 57 do {
61 xor(iv, src, bsize); 58 crypto_xor(iv, src, bsize);
62 fn(crypto_cipher_tfm(tfm), dst, iv); 59 fn(crypto_cipher_tfm(tfm), dst, iv);
63 memcpy(iv, dst, bsize); 60 memcpy(iv, dst, bsize);
64 xor(iv, src, bsize); 61 crypto_xor(iv, src, bsize);
65 62
66 src += bsize; 63 src += bsize;
67 dst += bsize; 64 dst += bsize;
@@ -72,9 +69,7 @@ static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
72 69
73static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc, 70static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc,
74 struct blkcipher_walk *walk, 71 struct blkcipher_walk *walk,
75 struct crypto_cipher *tfm, 72 struct crypto_cipher *tfm)
76 void (*xor)(u8 *, const u8 *,
77 unsigned int))
78{ 73{
79 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 74 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
80 crypto_cipher_alg(tfm)->cia_encrypt; 75 crypto_cipher_alg(tfm)->cia_encrypt;
@@ -86,10 +81,10 @@ static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc,
86 81
87 do { 82 do {
88 memcpy(tmpbuf, src, bsize); 83 memcpy(tmpbuf, src, bsize);
89 xor(iv, tmpbuf, bsize); 84 crypto_xor(iv, src, bsize);
90 fn(crypto_cipher_tfm(tfm), src, iv); 85 fn(crypto_cipher_tfm(tfm), src, iv);
91 memcpy(iv, src, bsize); 86 memcpy(iv, tmpbuf, bsize);
92 xor(iv, tmpbuf, bsize); 87 crypto_xor(iv, src, bsize);
93 88
94 src += bsize; 89 src += bsize;
95 } while ((nbytes -= bsize) >= bsize); 90 } while ((nbytes -= bsize) >= bsize);
@@ -107,7 +102,6 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
107 struct crypto_blkcipher *tfm = desc->tfm; 102 struct crypto_blkcipher *tfm = desc->tfm;
108 struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); 103 struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
109 struct crypto_cipher *child = ctx->child; 104 struct crypto_cipher *child = ctx->child;
110 void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
111 int err; 105 int err;
112 106
113 blkcipher_walk_init(&walk, dst, src, nbytes); 107 blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -115,11 +109,11 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
115 109
116 while ((nbytes = walk.nbytes)) { 110 while ((nbytes = walk.nbytes)) {
117 if (walk.src.virt.addr == walk.dst.virt.addr) 111 if (walk.src.virt.addr == walk.dst.virt.addr)
118 nbytes = crypto_pcbc_encrypt_inplace(desc, &walk, child, 112 nbytes = crypto_pcbc_encrypt_inplace(desc, &walk,
119 xor); 113 child);
120 else 114 else
121 nbytes = crypto_pcbc_encrypt_segment(desc, &walk, child, 115 nbytes = crypto_pcbc_encrypt_segment(desc, &walk,
122 xor); 116 child);
123 err = blkcipher_walk_done(desc, &walk, nbytes); 117 err = blkcipher_walk_done(desc, &walk, nbytes);
124 } 118 }
125 119
@@ -128,9 +122,7 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
128 122
129static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc, 123static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
130 struct blkcipher_walk *walk, 124 struct blkcipher_walk *walk,
131 struct crypto_cipher *tfm, 125 struct crypto_cipher *tfm)
132 void (*xor)(u8 *, const u8 *,
133 unsigned int))
134{ 126{
135 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 127 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
136 crypto_cipher_alg(tfm)->cia_decrypt; 128 crypto_cipher_alg(tfm)->cia_decrypt;
@@ -142,9 +134,9 @@ static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
142 134
143 do { 135 do {
144 fn(crypto_cipher_tfm(tfm), dst, src); 136 fn(crypto_cipher_tfm(tfm), dst, src);
145 xor(dst, iv, bsize); 137 crypto_xor(dst, iv, bsize);
146 memcpy(iv, src, bsize); 138 memcpy(iv, src, bsize);
147 xor(iv, dst, bsize); 139 crypto_xor(iv, dst, bsize);
148 140
149 src += bsize; 141 src += bsize;
150 dst += bsize; 142 dst += bsize;
@@ -157,9 +149,7 @@ static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
157 149
158static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc, 150static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc,
159 struct blkcipher_walk *walk, 151 struct blkcipher_walk *walk,
160 struct crypto_cipher *tfm, 152 struct crypto_cipher *tfm)
161 void (*xor)(u8 *, const u8 *,
162 unsigned int))
163{ 153{
164 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = 154 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
165 crypto_cipher_alg(tfm)->cia_decrypt; 155 crypto_cipher_alg(tfm)->cia_decrypt;
@@ -172,9 +162,9 @@ static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc,
172 do { 162 do {
173 memcpy(tmpbuf, src, bsize); 163 memcpy(tmpbuf, src, bsize);
174 fn(crypto_cipher_tfm(tfm), src, src); 164 fn(crypto_cipher_tfm(tfm), src, src);
175 xor(src, iv, bsize); 165 crypto_xor(src, iv, bsize);
176 memcpy(iv, tmpbuf, bsize); 166 memcpy(iv, tmpbuf, bsize);
177 xor(iv, src, bsize); 167 crypto_xor(iv, src, bsize);
178 168
179 src += bsize; 169 src += bsize;
180 } while ((nbytes -= bsize) >= bsize); 170 } while ((nbytes -= bsize) >= bsize);
@@ -192,7 +182,6 @@ static int crypto_pcbc_decrypt(struct blkcipher_desc *desc,
192 struct crypto_blkcipher *tfm = desc->tfm; 182 struct crypto_blkcipher *tfm = desc->tfm;
193 struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); 183 struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
194 struct crypto_cipher *child = ctx->child; 184 struct crypto_cipher *child = ctx->child;
195 void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
196 int err; 185 int err;
197 186
198 blkcipher_walk_init(&walk, dst, src, nbytes); 187 blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -200,48 +189,17 @@ static int crypto_pcbc_decrypt(struct blkcipher_desc *desc,
200 189
201 while ((nbytes = walk.nbytes)) { 190 while ((nbytes = walk.nbytes)) {
202 if (walk.src.virt.addr == walk.dst.virt.addr) 191 if (walk.src.virt.addr == walk.dst.virt.addr)
203 nbytes = crypto_pcbc_decrypt_inplace(desc, &walk, child, 192 nbytes = crypto_pcbc_decrypt_inplace(desc, &walk,
204 xor); 193 child);
205 else 194 else
206 nbytes = crypto_pcbc_decrypt_segment(desc, &walk, child, 195 nbytes = crypto_pcbc_decrypt_segment(desc, &walk,
207 xor); 196 child);
208 err = blkcipher_walk_done(desc, &walk, nbytes); 197 err = blkcipher_walk_done(desc, &walk, nbytes);
209 } 198 }
210 199
211 return err; 200 return err;
212} 201}
213 202
214static void xor_byte(u8 *a, const u8 *b, unsigned int bs)
215{
216 do {
217 *a++ ^= *b++;
218 } while (--bs);
219}
220
221static void xor_quad(u8 *dst, const u8 *src, unsigned int bs)
222{
223 u32 *a = (u32 *)dst;
224 u32 *b = (u32 *)src;
225
226 do {
227 *a++ ^= *b++;
228 } while ((bs -= 4));
229}
230
231static void xor_64(u8 *a, const u8 *b, unsigned int bs)
232{
233 ((u32 *)a)[0] ^= ((u32 *)b)[0];
234 ((u32 *)a)[1] ^= ((u32 *)b)[1];
235}
236
237static void xor_128(u8 *a, const u8 *b, unsigned int bs)
238{
239 ((u32 *)a)[0] ^= ((u32 *)b)[0];
240 ((u32 *)a)[1] ^= ((u32 *)b)[1];
241 ((u32 *)a)[2] ^= ((u32 *)b)[2];
242 ((u32 *)a)[3] ^= ((u32 *)b)[3];
243}
244
245static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm) 203static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm)
246{ 204{
247 struct crypto_instance *inst = (void *)tfm->__crt_alg; 205 struct crypto_instance *inst = (void *)tfm->__crt_alg;
@@ -249,22 +207,6 @@ static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm)
249 struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm); 207 struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm);
250 struct crypto_cipher *cipher; 208 struct crypto_cipher *cipher;
251 209
252 switch (crypto_tfm_alg_blocksize(tfm)) {
253 case 8:
254 ctx->xor = xor_64;
255 break;
256
257 case 16:
258 ctx->xor = xor_128;
259 break;
260
261 default:
262 if (crypto_tfm_alg_blocksize(tfm) % 4)
263 ctx->xor = xor_byte;
264 else
265 ctx->xor = xor_quad;
266 }
267
268 cipher = crypto_spawn_cipher(spawn); 210 cipher = crypto_spawn_cipher(spawn);
269 if (IS_ERR(cipher)) 211 if (IS_ERR(cipher))
270 return PTR_ERR(cipher); 212 return PTR_ERR(cipher);
@@ -304,8 +246,9 @@ static struct crypto_instance *crypto_pcbc_alloc(struct rtattr **tb)
304 inst->alg.cra_alignmask = alg->cra_alignmask; 246 inst->alg.cra_alignmask = alg->cra_alignmask;
305 inst->alg.cra_type = &crypto_blkcipher_type; 247 inst->alg.cra_type = &crypto_blkcipher_type;
306 248
307 if (!(alg->cra_blocksize % 4)) 249 /* We access the data as u32s when xoring. */
308 inst->alg.cra_alignmask |= 3; 250 inst->alg.cra_alignmask |= __alignof__(u32) - 1;
251
309 inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize; 252 inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
310 inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize; 253 inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
311 inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize; 254 inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;