Blame view
crypto/chacha_generic.c
3.87 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
c08d0e647 crypto: chacha20 ... |
2 |
/* |
aa7624093 crypto: chacha - ... |
3 |
* ChaCha and XChaCha stream ciphers, including ChaCha20 (RFC7539) |
c08d0e647 crypto: chacha20 ... |
4 5 |
* * Copyright (C) 2015 Martin Willi |
de61d7ae5 crypto: chacha20-... |
6 |
* Copyright (C) 2018 Google LLC |
c08d0e647 crypto: chacha20 ... |
7 |
*/ |
dbd872a12 crypto: chacha20 ... |
8 |
#include <asm/unaligned.h> |
c08d0e647 crypto: chacha20 ... |
9 |
#include <crypto/algapi.h> |
5fb8ef258 crypto: chacha - ... |
10 |
#include <crypto/internal/chacha.h> |
9ae433bc7 crypto: chacha20 ... |
11 12 |
#include <crypto/internal/skcipher.h> #include <linux/module.h> |
c08d0e647 crypto: chacha20 ... |
13 |
|
1ca1b9179 crypto: chacha20-... |
14 |
static int chacha_stream_xor(struct skcipher_request *req, |
860ab2e50 crypto: chacha - ... |
15 |
const struct chacha_ctx *ctx, const u8 *iv) |
de61d7ae5 crypto: chacha20-... |
16 17 18 19 20 21 |
{ struct skcipher_walk walk; u32 state[16]; int err; err = skcipher_walk_virt(&walk, req, false); |
22cf70536 crypto: chacha - ... |
22 |
chacha_init_generic(state, ctx->key, iv); |
de61d7ae5 crypto: chacha20-... |
23 24 25 26 27 |
while (walk.nbytes > 0) { unsigned int nbytes = walk.nbytes; if (nbytes < walk.total) |
7aceaaef0 crypto: chacha-ge... |
28 |
nbytes = round_down(nbytes, CHACHA_BLOCK_SIZE); |
de61d7ae5 crypto: chacha20-... |
29 |
|
5fb8ef258 crypto: chacha - ... |
30 31 |
chacha_crypt_generic(state, walk.dst.virt.addr, walk.src.virt.addr, nbytes, ctx->nrounds); |
de61d7ae5 crypto: chacha20-... |
32 33 34 35 36 |
err = skcipher_walk_done(&walk, walk.nbytes - nbytes); } return err; } |
22cf70536 crypto: chacha - ... |
37 |
static int crypto_chacha_crypt(struct skcipher_request *req) |
c08d0e647 crypto: chacha20 ... |
38 |
{ |
9ae433bc7 crypto: chacha20 ... |
39 |
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
1ca1b9179 crypto: chacha20-... |
40 |
struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); |
c08d0e647 crypto: chacha20 ... |
41 |
|
1ca1b9179 crypto: chacha20-... |
42 |
return chacha_stream_xor(req, ctx, req->iv); |
de61d7ae5 crypto: chacha20-... |
43 |
} |
c08d0e647 crypto: chacha20 ... |
44 |
|
22cf70536 crypto: chacha - ... |
45 |
static int crypto_xchacha_crypt(struct skcipher_request *req) |
de61d7ae5 crypto: chacha20-... |
46 47 |
{ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
1ca1b9179 crypto: chacha20-... |
48 49 |
struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); struct chacha_ctx subctx; |
de61d7ae5 crypto: chacha20-... |
50 51 |
u32 state[16]; u8 real_iv[16]; |
4de437265 crypto: chacha20 ... |
52 |
|
de61d7ae5 crypto: chacha20-... |
53 |
/* Compute the subkey given the original key and first 128 nonce bits */ |
22cf70536 crypto: chacha - ... |
54 |
chacha_init_generic(state, ctx->key, req->iv); |
5fb8ef258 crypto: chacha - ... |
55 |
hchacha_block_generic(state, subctx.key, ctx->nrounds); |
1ca1b9179 crypto: chacha20-... |
56 |
subctx.nrounds = ctx->nrounds; |
4de437265 crypto: chacha20 ... |
57 |
|
de61d7ae5 crypto: chacha20-... |
58 59 60 |
/* Build the real IV */ memcpy(&real_iv[0], req->iv + 24, 8); /* stream position */ memcpy(&real_iv[8], req->iv + 16, 8); /* remaining 64 nonce bits */ |
c08d0e647 crypto: chacha20 ... |
61 |
|
de61d7ae5 crypto: chacha20-... |
62 |
/* Generate the stream and XOR it with the data */ |
1ca1b9179 crypto: chacha20-... |
63 |
return chacha_stream_xor(req, &subctx, real_iv); |
c08d0e647 crypto: chacha20 ... |
64 |
} |
de61d7ae5 crypto: chacha20-... |
65 66 67 68 69 70 71 |
static struct skcipher_alg algs[] = { { .base.cra_name = "chacha20", .base.cra_driver_name = "chacha20-generic", .base.cra_priority = 100, .base.cra_blocksize = 1, |
1ca1b9179 crypto: chacha20-... |
72 |
.base.cra_ctxsize = sizeof(struct chacha_ctx), |
de61d7ae5 crypto: chacha20-... |
73 |
.base.cra_module = THIS_MODULE, |
1ca1b9179 crypto: chacha20-... |
74 75 76 77 |
.min_keysize = CHACHA_KEY_SIZE, .max_keysize = CHACHA_KEY_SIZE, .ivsize = CHACHA_IV_SIZE, .chunksize = CHACHA_BLOCK_SIZE, |
2043323a7 crypto: chacha_ge... |
78 |
.setkey = chacha20_setkey, |
1ca1b9179 crypto: chacha20-... |
79 80 |
.encrypt = crypto_chacha_crypt, .decrypt = crypto_chacha_crypt, |
de61d7ae5 crypto: chacha20-... |
81 82 83 84 85 |
}, { .base.cra_name = "xchacha20", .base.cra_driver_name = "xchacha20-generic", .base.cra_priority = 100, .base.cra_blocksize = 1, |
1ca1b9179 crypto: chacha20-... |
86 |
.base.cra_ctxsize = sizeof(struct chacha_ctx), |
de61d7ae5 crypto: chacha20-... |
87 |
.base.cra_module = THIS_MODULE, |
1ca1b9179 crypto: chacha20-... |
88 89 90 91 |
.min_keysize = CHACHA_KEY_SIZE, .max_keysize = CHACHA_KEY_SIZE, .ivsize = XCHACHA_IV_SIZE, .chunksize = CHACHA_BLOCK_SIZE, |
2043323a7 crypto: chacha_ge... |
92 |
.setkey = chacha20_setkey, |
1ca1b9179 crypto: chacha20-... |
93 94 |
.encrypt = crypto_xchacha_crypt, .decrypt = crypto_xchacha_crypt, |
aa7624093 crypto: chacha - ... |
95 96 97 98 99 100 101 102 103 104 105 106 |
}, { .base.cra_name = "xchacha12", .base.cra_driver_name = "xchacha12-generic", .base.cra_priority = 100, .base.cra_blocksize = 1, .base.cra_ctxsize = sizeof(struct chacha_ctx), .base.cra_module = THIS_MODULE, .min_keysize = CHACHA_KEY_SIZE, .max_keysize = CHACHA_KEY_SIZE, .ivsize = XCHACHA_IV_SIZE, .chunksize = CHACHA_BLOCK_SIZE, |
2043323a7 crypto: chacha_ge... |
107 |
.setkey = chacha12_setkey, |
aa7624093 crypto: chacha - ... |
108 109 |
.encrypt = crypto_xchacha_crypt, .decrypt = crypto_xchacha_crypt, |
de61d7ae5 crypto: chacha20-... |
110 |
} |
c08d0e647 crypto: chacha20 ... |
111 |
}; |
1ca1b9179 crypto: chacha20-... |
112 |
static int __init chacha_generic_mod_init(void) |
c08d0e647 crypto: chacha20 ... |
113 |
{ |
de61d7ae5 crypto: chacha20-... |
114 |
return crypto_register_skciphers(algs, ARRAY_SIZE(algs)); |
c08d0e647 crypto: chacha20 ... |
115 |
} |
1ca1b9179 crypto: chacha20-... |
116 |
static void __exit chacha_generic_mod_fini(void) |
c08d0e647 crypto: chacha20 ... |
117 |
{ |
de61d7ae5 crypto: chacha20-... |
118 |
crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); |
c08d0e647 crypto: chacha20 ... |
119 |
} |
c4741b230 crypto: run initc... |
120 |
subsys_initcall(chacha_generic_mod_init); |
1ca1b9179 crypto: chacha20-... |
121 |
module_exit(chacha_generic_mod_fini); |
c08d0e647 crypto: chacha20 ... |
122 123 124 |
MODULE_LICENSE("GPL"); MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); |
1ca1b9179 crypto: chacha20-... |
125 |
MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (generic)"); |
c08d0e647 crypto: chacha20 ... |
126 127 |
MODULE_ALIAS_CRYPTO("chacha20"); MODULE_ALIAS_CRYPTO("chacha20-generic"); |
de61d7ae5 crypto: chacha20-... |
128 129 |
MODULE_ALIAS_CRYPTO("xchacha20"); MODULE_ALIAS_CRYPTO("xchacha20-generic"); |
aa7624093 crypto: chacha - ... |
130 131 |
MODULE_ALIAS_CRYPTO("xchacha12"); MODULE_ALIAS_CRYPTO("xchacha12-generic"); |