| 1 | |
| 2 | |
| 3 | * Adiantum length-preserving encryption mode
|
| 4 | *
|
| 5 | * Copyright 2018 Google LLC
|
| 6 |
|
| 7 |
|
| 8 | |
| 9 | * Adiantum is a tweakable, length-preserving encryption mode designed for fast
|
| 10 | * and secure disk encryption, especially on CPUs without dedicated crypto
|
| 11 | * instructions. Adiantum encrypts each sector using the XChaCha12 stream
|
| 12 | * cipher, two passes of an ε-almost-∆-universal (ε-∆U) hash function based on
|
| 13 | * NH and Poly1305, and an invocation of the AES-256 block cipher on a single
|
| 14 | * 16-byte block. See the paper for details:
|
| 15 | *
|
| 16 | * Adiantum: length-preserving encryption for entry-level processors
|
| 17 | * (https://eprint.iacr.org/2018/720.pdf)
|
| 18 | *
|
| 19 | * For flexibility, this implementation also allows other ciphers:
|
| 20 | *
|
| 21 | * - Stream cipher: XChaCha12 or XChaCha20
|
| 22 | * - Block cipher: any with a 128-bit block size and 256-bit key
|
| 23 |
|
| 24 |
|
| 25 | #include <crypto/b128ops.h>
|
| 26 | #include <crypto/chacha.h>
|
| 27 | #include <crypto/internal/cipher.h>
|
| 28 | #include <crypto/internal/poly1305.h>
|
| 29 | #include <crypto/internal/skcipher.h>
|
| 30 | #include <crypto/nh.h>
|
| 31 | #include <crypto/scatterwalk.h>
|
| 32 | #include <linux/module.h>
|
| 33 |
|
| 34 | |
| 35 | * Size of right-hand part of input data, in bytes; also the size of the block
|
| 36 | * cipher's block size and the hash function's output.
|
| 37 |
|
| 38 | #define BLOCKCIPHER_BLOCK_SIZE 16
|
| 39 |
|
| 40 |
|
| 41 | #define BLOCKCIPHER_KEY_SIZE 32
|
| 42 |
|
| 43 |
|
| 44 | #define HASH_KEY_SIZE (2 * POLY1305_BLOCK_SIZE + NH_KEY_BYTES)
|
| 45 |
|
| 46 | |
| 47 | * The specification allows variable-length tweaks, but Linux's crypto API
|
| 48 | * currently only allows algorithms to support a single length. The "natural"
|
| 49 | * tweak length for Adiantum is 16, since that fits into one Poly1305 block for
|
| 50 | * the best performance. But longer tweaks are useful for fscrypt, to avoid
|
| 51 | * needing to derive per-file keys. So instead we use two blocks, or 32 bytes.
|
| 52 |
|
| 53 | #define TWEAK_SIZE 32
|
| 54 |
|
| 55 | struct adiantum_instance_ctx {
|
| 56 | struct crypto_skcipher_spawn streamcipher_spawn;
|
| 57 | struct crypto_cipher_spawn blockcipher_spawn;
|
| 58 | };
|
| 59 |
|
| 60 | struct adiantum_tfm_ctx {
|
| 61 | struct crypto_skcipher *streamcipher;
|
| 62 | struct crypto_cipher *blockcipher;
|
| 63 | struct poly1305_core_key header_hash_key;
|
| 64 | struct poly1305_core_key msg_poly_key;
|
| 65 | u32 nh_key[NH_KEY_WORDS];
|
| 66 | };
|
| 67 |
|
| 68 | struct nhpoly1305_ctx {
|
| 69 |
|
| 70 | struct poly1305_state poly_state;
|
| 71 |
|
| 72 |
|
| 73 | u8 buffer[NH_MESSAGE_UNIT];
|
| 74 | unsigned int buflen;
|
| 75 |
|
| 76 | |
| 77 | * Number of bytes remaining until the current NH message reaches
|
| 78 | * NH_MESSAGE_BYTES. When nonzero, 'nh_hash' holds the partial NH hash.
|
| 79 |
|
| 80 | unsigned int nh_remaining;
|
| 81 |
|
| 82 | __le64 nh_hash[NH_NUM_PASSES];
|
| 83 | };
|
| 84 |
|
| 85 | struct adiantum_request_ctx {
|
| 86 | |
| 87 | * skcipher sub-request size is unknown at compile-time, so it needs to
|
| 88 | * go after the members with known sizes.
|
| 89 |
|
| 90 | union {
|
| 91 | struct nhpoly1305_ctx hash_ctx;
|
| 92 | struct skcipher_request streamcipher_req;
|
| 93 | } u;
|
| 94 | };
|
| 95 |
|
| 96 | |
| 97 | * Given the XChaCha stream key K_S, derive the block cipher key K_E and the
|
| 98 | * hash key K_H as follows:
|
| 99 | *
|
| 100 | * K_E || K_H || ... = XChaCha(key=K_S, nonce=1||0^191)
|
| 101 | *
|
| 102 | * Note that this denotes using bits from the XChaCha keystream, which here we
|
| 103 | * get indirectly by encrypting a buffer containing all 0's.
|
| 104 |
|
| 105 | static int adiantum_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
| 106 | unsigned int keylen)
|
| 107 | {
|
| 108 | struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 109 | struct {
|
| 110 | u8 iv[XCHACHA_IV_SIZE];
|
| 111 | u8 derived_keys[BLOCKCIPHER_KEY_SIZE + HASH_KEY_SIZE];
|
| 112 | struct scatterlist sg;
|
| 113 | struct crypto_wait wait;
|
| 114 | struct skcipher_request req;
|
| 115 | } *data;
|
| 116 | u8 *keyp;
|
| 117 | int err;
|
| 118 |
|
| 119 |
|
| 120 | crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
|
| 121 | crypto_skcipher_set_flags(tctx->streamcipher,
|
| 122 | crypto_skcipher_get_flags(tfm) &
|
| 123 | CRYPTO_TFM_REQ_MASK);
|
| 124 | err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
|
| 125 | if (err)
|
| 126 | return err;
|
| 127 |
|
| 128 |
|
| 129 | data = kzalloc(sizeof(*data) +
|
| 130 | crypto_skcipher_reqsize(tctx->streamcipher), GFP_KERNEL);
|
| 131 | if (!data)
|
| 132 | return -ENOMEM;
|
| 133 | data->iv[0] = 1;
|
| 134 | sg_init_one(&data->sg, data->derived_keys, sizeof(data->derived_keys));
|
| 135 | crypto_init_wait(&data->wait);
|
| 136 | skcipher_request_set_tfm(&data->req, tctx->streamcipher);
|
| 137 | skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
|
| 138 | CRYPTO_TFM_REQ_MAY_BACKLOG,
|
| 139 | crypto_req_done, &data->wait);
|
| 140 | skcipher_request_set_crypt(&data->req, &data->sg, &data->sg,
|
| 141 | sizeof(data->derived_keys), data->iv);
|
| 142 | err = crypto_wait_req(crypto_skcipher_encrypt(&data->req), &data->wait);
|
| 143 | if (err)
|
| 144 | goto out;
|
| 145 | keyp = data->derived_keys;
|
| 146 |
|
| 147 |
|
| 148 | crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
|
| 149 | crypto_cipher_set_flags(tctx->blockcipher,
|
| 150 | crypto_skcipher_get_flags(tfm) &
|
| 151 | CRYPTO_TFM_REQ_MASK);
|
| 152 | err = crypto_cipher_setkey(tctx->blockcipher, keyp,
|
| 153 | BLOCKCIPHER_KEY_SIZE);
|
| 154 | if (err)
|
| 155 | goto out;
|
| 156 | keyp += BLOCKCIPHER_KEY_SIZE;
|
| 157 |
|
| 158 |
|
| 159 | poly1305_core_setkey(&tctx->header_hash_key, keyp);
|
| 160 | keyp += POLY1305_BLOCK_SIZE;
|
| 161 | poly1305_core_setkey(&tctx->msg_poly_key, keyp);
|
| 162 | keyp += POLY1305_BLOCK_SIZE;
|
| 163 | for (int i = 0; i < NH_KEY_WORDS; i++)
|
| 164 | tctx->nh_key[i] = get_unaligned_le32(&keyp[i * 4]);
|
| 165 | keyp += NH_KEY_BYTES;
|
| 166 | WARN_ON(keyp != &data->derived_keys[ARRAY_SIZE(data->derived_keys)]);
|
| 167 | out:
|
| 168 | kfree_sensitive(data);
|
| 169 | return err;
|
| 170 | }
|
| 171 |
|
| 172 |
|
| 173 | static inline void le128_add(le128 *r, const le128 *v1, const le128 *v2)
|
| 174 | {
|
| 175 | u64 x = le64_to_cpu(v1->b);
|
| 176 | u64 y = le64_to_cpu(v2->b);
|
| 177 |
|
| 178 | r->b = cpu_to_le64(x + y);
|
| 179 | r->a = cpu_to_le64(le64_to_cpu(v1->a) + le64_to_cpu(v2->a) +
|
| 180 | (x + y < x));
|
| 181 | }
|
| 182 |
|
| 183 |
|
| 184 | static inline void le128_sub(le128 *r, const le128 *v1, const le128 *v2)
|
| 185 | {
|
| 186 | u64 x = le64_to_cpu(v1->b);
|
| 187 | u64 y = le64_to_cpu(v2->b);
|
| 188 |
|
| 189 | r->b = cpu_to_le64(x - y);
|
| 190 | r->a = cpu_to_le64(le64_to_cpu(v1->a) - le64_to_cpu(v2->a) -
|
| 191 | (x - y > x));
|
| 192 | }
|
| 193 |
|
| 194 | |
| 195 | * Apply the Poly1305 ε-∆U hash function to (bulk length, tweak) and save the
|
| 196 | * result to @out. This is the calculation
|
| 197 | *
|
| 198 | * H_T ← Poly1305_{K_T}(bin_{128}(|L|) || T)
|
| 199 | *
|
| 200 | * from the procedure in section 6.4 of the Adiantum paper. The resulting value
|
| 201 | * is reused in both the first and second hash steps. Specifically, it's added
|
| 202 | * to the result of an independently keyed ε-∆U hash function (for equal length
|
| 203 | * inputs only) taken over the left-hand part (the "bulk") of the message, to
|
| 204 | * give the overall Adiantum hash of the (tweak, left-hand part) pair.
|
| 205 |
|
| 206 | static void adiantum_hash_header(struct skcipher_request *req, le128 *out)
|
| 207 | {
|
| 208 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
| 209 | const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 210 | const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
|
| 211 | struct {
|
| 212 | __le64 message_bits;
|
| 213 | __le64 padding;
|
| 214 | } header = {
|
| 215 | .message_bits = cpu_to_le64((u64)bulk_len * 8)
|
| 216 | };
|
| 217 | struct poly1305_state state;
|
| 218 |
|
| 219 | poly1305_core_init(&state);
|
| 220 |
|
| 221 | BUILD_BUG_ON(sizeof(header) % POLY1305_BLOCK_SIZE != 0);
|
| 222 | poly1305_core_blocks(&state, &tctx->header_hash_key,
|
| 223 | &header, sizeof(header) / POLY1305_BLOCK_SIZE, 1);
|
| 224 |
|
| 225 | BUILD_BUG_ON(TWEAK_SIZE % POLY1305_BLOCK_SIZE != 0);
|
| 226 | poly1305_core_blocks(&state, &tctx->header_hash_key, req->iv,
|
| 227 | TWEAK_SIZE / POLY1305_BLOCK_SIZE, 1);
|
| 228 |
|
| 229 | poly1305_core_emit(&state, NULL, out);
|
| 230 | }
|
| 231 |
|
| 232 |
|
| 233 | static void process_nh_hash_value(struct nhpoly1305_ctx *ctx,
|
| 234 | const struct adiantum_tfm_ctx *key)
|
| 235 | {
|
| 236 | static_assert(NH_HASH_BYTES % POLY1305_BLOCK_SIZE == 0);
|
| 237 |
|
| 238 | poly1305_core_blocks(&ctx->poly_state, &key->msg_poly_key, ctx->nh_hash,
|
| 239 | NH_HASH_BYTES / POLY1305_BLOCK_SIZE, 1);
|
| 240 | }
|
| 241 |
|
| 242 | |
| 243 | * Feed the next portion of the message data, as a whole number of 16-byte
|
| 244 | * "NH message units", through NH and Poly1305. Each NH hash is taken over
|
| 245 | * 1024 bytes, except possibly the final one which is taken over a multiple of
|
| 246 | * 16 bytes up to 1024. Also, in the case where data is passed in misaligned
|
| 247 | * chunks, we combine partial hashes; the end result is the same either way.
|
| 248 |
|
| 249 | static void nhpoly1305_units(struct nhpoly1305_ctx *ctx,
|
| 250 | const struct adiantum_tfm_ctx *key,
|
| 251 | const u8 *data, size_t len)
|
| 252 | {
|
| 253 | do {
|
| 254 | unsigned int bytes;
|
| 255 |
|
| 256 | if (ctx->nh_remaining == 0) {
|
| 257 |
|
| 258 | bytes = min(len, NH_MESSAGE_BYTES);
|
| 259 | nh(key->nh_key, data, bytes, ctx->nh_hash);
|
| 260 | ctx->nh_remaining = NH_MESSAGE_BYTES - bytes;
|
| 261 | } else {
|
| 262 |
|
| 263 | __le64 tmp_hash[NH_NUM_PASSES];
|
| 264 | unsigned int pos;
|
| 265 |
|
| 266 | pos = NH_MESSAGE_BYTES - ctx->nh_remaining;
|
| 267 | bytes = min(len, ctx->nh_remaining);
|
| 268 | nh(&key->nh_key[pos / 4], data, bytes, tmp_hash);
|
| 269 | for (int i = 0; i < NH_NUM_PASSES; i++)
|
| 270 | le64_add_cpu(&ctx->nh_hash[i],
|
| 271 | le64_to_cpu(tmp_hash[i]));
|
| 272 | ctx->nh_remaining -= bytes;
|
| 273 | }
|
| 274 | if (ctx->nh_remaining == 0)
|
| 275 | process_nh_hash_value(ctx, key);
|
| 276 | data += bytes;
|
| 277 | len -= bytes;
|
| 278 | } while (len);
|
| 279 | }
|
| 280 |
|
| 281 | static void nhpoly1305_init(struct nhpoly1305_ctx *ctx)
|
| 282 | {
|
| 283 | poly1305_core_init(&ctx->poly_state);
|
| 284 | ctx->buflen = 0;
|
| 285 | ctx->nh_remaining = 0;
|
| 286 | }
|
| 287 |
|
| 288 | static void nhpoly1305_update(struct nhpoly1305_ctx *ctx,
|
| 289 | const struct adiantum_tfm_ctx *key,
|
| 290 | const u8 *data, size_t len)
|
| 291 | {
|
| 292 | unsigned int bytes;
|
| 293 |
|
| 294 | if (ctx->buflen) {
|
| 295 | bytes = min(len, (int)NH_MESSAGE_UNIT - ctx->buflen);
|
| 296 | memcpy(&ctx->buffer[ctx->buflen], data, bytes);
|
| 297 | ctx->buflen += bytes;
|
| 298 | if (ctx->buflen < NH_MESSAGE_UNIT)
|
| 299 | return;
|
| 300 | nhpoly1305_units(ctx, key, ctx->buffer, NH_MESSAGE_UNIT);
|
| 301 | ctx->buflen = 0;
|
| 302 | data += bytes;
|
| 303 | len -= bytes;
|
| 304 | }
|
| 305 |
|
| 306 | if (len >= NH_MESSAGE_UNIT) {
|
| 307 | bytes = round_down(len, NH_MESSAGE_UNIT);
|
| 308 | nhpoly1305_units(ctx, key, data, bytes);
|
| 309 | data += bytes;
|
| 310 | len -= bytes;
|
| 311 | }
|
| 312 |
|
| 313 | if (len) {
|
| 314 | memcpy(ctx->buffer, data, len);
|
| 315 | ctx->buflen = len;
|
| 316 | }
|
| 317 | }
|
| 318 |
|
| 319 | static void nhpoly1305_final(struct nhpoly1305_ctx *ctx,
|
| 320 | const struct adiantum_tfm_ctx *key, le128 *out)
|
| 321 | {
|
| 322 | if (ctx->buflen) {
|
| 323 | memset(&ctx->buffer[ctx->buflen], 0,
|
| 324 | NH_MESSAGE_UNIT - ctx->buflen);
|
| 325 | nhpoly1305_units(ctx, key, ctx->buffer, NH_MESSAGE_UNIT);
|
| 326 | }
|
| 327 |
|
| 328 | if (ctx->nh_remaining)
|
| 329 | process_nh_hash_value(ctx, key);
|
| 330 |
|
| 331 | poly1305_core_emit(&ctx->poly_state, NULL, out);
|
| 332 | }
|
| 333 |
|
| 334 | |
| 335 | * Hash the left-hand part (the "bulk") of the message as follows:
|
| 336 | *
|
| 337 | * H_L ← Poly1305_{K_L}(NH_{K_N}(pad_{128}(L)))
|
| 338 | *
|
| 339 | * See section 6.4 of the Adiantum paper. This is an ε-almost-∆-universal
|
| 340 | * (ε-∆U) hash function for equal-length inputs over Z/(2^{128}Z), where the "∆"
|
| 341 | * operation is addition. It hashes 1024-byte chunks of the input with the NH
|
| 342 | * hash function, reducing the input length by 32x. The resulting NH hashes are
|
| 343 | * evaluated as a polynomial in GF(2^{130}-5), like in the Poly1305 MAC. Note
|
| 344 | * that the polynomial evaluation by itself would suffice to achieve the ε-∆U
|
| 345 | * property; NH is used for performance since it's much faster than Poly1305.
|
| 346 |
|
| 347 | static void adiantum_hash_message(struct skcipher_request *req,
|
| 348 | struct scatterlist *sgl, le128 *out)
|
| 349 | {
|
| 350 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
| 351 | const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 352 | struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
|
| 353 | unsigned int len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
|
| 354 | struct scatter_walk walk;
|
| 355 |
|
| 356 | nhpoly1305_init(&rctx->u.hash_ctx);
|
| 357 | scatterwalk_start(&walk, sgl);
|
| 358 | while (len) {
|
| 359 | unsigned int n = scatterwalk_next(&walk, len);
|
| 360 |
|
| 361 | nhpoly1305_update(&rctx->u.hash_ctx, tctx, walk.addr, n);
|
| 362 | scatterwalk_done_src(&walk, n);
|
| 363 | len -= n;
|
| 364 | }
|
| 365 | nhpoly1305_final(&rctx->u.hash_ctx, tctx, out);
|
| 366 | }
|
| 367 |
|
| 368 | static int adiantum_crypt(struct skcipher_request *req, bool enc)
|
| 369 | {
|
| 370 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
| 371 | const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 372 | struct adiantum_request_ctx *rctx = skcipher_request_ctx(req);
|
| 373 | const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
|
| 374 | struct scatterlist *src = req->src, *dst = req->dst;
|
| 375 | |
| 376 | * Buffer for right-hand part of data, i.e.
|
| 377 | *
|
| 378 | * P_L => P_M => C_M => C_R when encrypting, or
|
| 379 | * C_R => C_M => P_M => P_L when decrypting.
|
| 380 | *
|
| 381 | * Also used to build the IV for the stream cipher.
|
| 382 |
|
| 383 | union {
|
| 384 | u8 bytes[XCHACHA_IV_SIZE];
|
| 385 | __le32 words[XCHACHA_IV_SIZE / sizeof(__le32)];
|
| 386 | le128 bignum;
|
| 387 | } rbuf;
|
| 388 | le128 header_hash, msg_hash;
|
| 389 | unsigned int stream_len;
|
| 390 | int err;
|
| 391 |
|
| 392 | if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
|
| 393 | return -EINVAL;
|
| 394 |
|
| 395 | |
| 396 | * First hash step
|
| 397 | * enc: P_M = P_R + H_{K_H}(T, P_L)
|
| 398 | * dec: C_M = C_R + H_{K_H}(T, C_L)
|
| 399 |
|
| 400 | adiantum_hash_header(req, &header_hash);
|
| 401 | if (src->length >= req->cryptlen &&
|
| 402 | src->offset + req->cryptlen <= PAGE_SIZE) {
|
| 403 |
|
| 404 | void *virt = kmap_local_page(sg_page(src)) + src->offset;
|
| 405 |
|
| 406 | nhpoly1305_init(&rctx->u.hash_ctx);
|
| 407 | nhpoly1305_update(&rctx->u.hash_ctx, tctx, virt, bulk_len);
|
| 408 | nhpoly1305_final(&rctx->u.hash_ctx, tctx, &msg_hash);
|
| 409 | memcpy(&rbuf.bignum, virt + bulk_len, sizeof(le128));
|
| 410 | kunmap_local(virt);
|
| 411 | } else {
|
| 412 |
|
| 413 | adiantum_hash_message(req, src, &msg_hash);
|
| 414 | memcpy_from_sglist(&rbuf.bignum, src, bulk_len, sizeof(le128));
|
| 415 | }
|
| 416 | le128_add(&rbuf.bignum, &rbuf.bignum, &header_hash);
|
| 417 | le128_add(&rbuf.bignum, &rbuf.bignum, &msg_hash);
|
| 418 |
|
| 419 |
|
| 420 | if (enc)
|
| 421 | crypto_cipher_encrypt_one(tctx->blockcipher, rbuf.bytes,
|
| 422 | rbuf.bytes);
|
| 423 |
|
| 424 |
|
| 425 | BUILD_BUG_ON(BLOCKCIPHER_BLOCK_SIZE != 16);
|
| 426 | BUILD_BUG_ON(XCHACHA_IV_SIZE != 32);
|
| 427 | rbuf.words[4] = cpu_to_le32(1);
|
| 428 | rbuf.words[5] = 0;
|
| 429 | rbuf.words[6] = 0;
|
| 430 | rbuf.words[7] = 0;
|
| 431 |
|
| 432 | |
| 433 | * XChaCha needs to be done on all the data except the last 16 bytes;
|
| 434 | * for disk encryption that usually means 4080 or 496 bytes. But ChaCha
|
| 435 | * implementations tend to be most efficient when passed a whole number
|
| 436 | * of 64-byte ChaCha blocks, or sometimes even a multiple of 256 bytes.
|
| 437 | * And here it doesn't matter whether the last 16 bytes are written to,
|
| 438 | * as the second hash step will overwrite them. Thus, round the XChaCha
|
| 439 | * length up to the next 64-byte boundary if possible.
|
| 440 |
|
| 441 | stream_len = bulk_len;
|
| 442 | if (round_up(stream_len, CHACHA_BLOCK_SIZE) <= req->cryptlen)
|
| 443 | stream_len = round_up(stream_len, CHACHA_BLOCK_SIZE);
|
| 444 |
|
| 445 | skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
|
| 446 | skcipher_request_set_crypt(&rctx->u.streamcipher_req, req->src,
|
| 447 | req->dst, stream_len, &rbuf);
|
| 448 | skcipher_request_set_callback(&rctx->u.streamcipher_req,
|
| 449 | req->base.flags, NULL, NULL);
|
| 450 | err = crypto_skcipher_encrypt(&rctx->u.streamcipher_req);
|
| 451 | if (err)
|
| 452 | return err;
|
| 453 |
|
| 454 |
|
| 455 | if (!enc)
|
| 456 | crypto_cipher_decrypt_one(tctx->blockcipher, rbuf.bytes,
|
| 457 | rbuf.bytes);
|
| 458 |
|
| 459 | |
| 460 | * Second hash step
|
| 461 | * enc: C_R = C_M - H_{K_H}(T, C_L)
|
| 462 | * dec: P_R = P_M - H_{K_H}(T, P_L)
|
| 463 |
|
| 464 | le128_sub(&rbuf.bignum, &rbuf.bignum, &header_hash);
|
| 465 | if (dst->length >= req->cryptlen &&
|
| 466 | dst->offset + req->cryptlen <= PAGE_SIZE) {
|
| 467 |
|
| 468 | struct page *page = sg_page(dst);
|
| 469 | void *virt = kmap_local_page(page) + dst->offset;
|
| 470 |
|
| 471 | nhpoly1305_init(&rctx->u.hash_ctx);
|
| 472 | nhpoly1305_update(&rctx->u.hash_ctx, tctx, virt, bulk_len);
|
| 473 | nhpoly1305_final(&rctx->u.hash_ctx, tctx, &msg_hash);
|
| 474 | le128_sub(&rbuf.bignum, &rbuf.bignum, &msg_hash);
|
| 475 | memcpy(virt + bulk_len, &rbuf.bignum, sizeof(le128));
|
| 476 | flush_dcache_page(page);
|
| 477 | kunmap_local(virt);
|
| 478 | } else {
|
| 479 |
|
| 480 | adiantum_hash_message(req, dst, &msg_hash);
|
| 481 | le128_sub(&rbuf.bignum, &rbuf.bignum, &msg_hash);
|
| 482 | memcpy_to_sglist(dst, bulk_len, &rbuf.bignum, sizeof(le128));
|
| 483 | }
|
| 484 | return 0;
|
| 485 | }
|
| 486 |
|
| 487 | static int adiantum_encrypt(struct skcipher_request *req)
|
| 488 | {
|
| 489 | return adiantum_crypt(req, true);
|
| 490 | }
|
| 491 |
|
| 492 | static int adiantum_decrypt(struct skcipher_request *req)
|
| 493 | {
|
| 494 | return adiantum_crypt(req, false);
|
| 495 | }
|
| 496 |
|
| 497 | static int adiantum_init_tfm(struct crypto_skcipher *tfm)
|
| 498 | {
|
| 499 | struct skcipher_instance *inst = skcipher_alg_instance(tfm);
|
| 500 | struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
|
| 501 | struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 502 | struct crypto_skcipher *streamcipher;
|
| 503 | struct crypto_cipher *blockcipher;
|
| 504 | int err;
|
| 505 |
|
| 506 | streamcipher = crypto_spawn_skcipher(&ictx->streamcipher_spawn);
|
| 507 | if (IS_ERR(streamcipher))
|
| 508 | return PTR_ERR(streamcipher);
|
| 509 |
|
| 510 | blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
|
| 511 | if (IS_ERR(blockcipher)) {
|
| 512 | err = PTR_ERR(blockcipher);
|
| 513 | goto err_free_streamcipher;
|
| 514 | }
|
| 515 |
|
| 516 | tctx->streamcipher = streamcipher;
|
| 517 | tctx->blockcipher = blockcipher;
|
| 518 |
|
| 519 | BUILD_BUG_ON(offsetofend(struct adiantum_request_ctx, u) !=
|
| 520 | sizeof(struct adiantum_request_ctx));
|
| 521 | crypto_skcipher_set_reqsize(
|
| 522 | tfm, max(sizeof(struct adiantum_request_ctx),
|
| 523 | offsetofend(struct adiantum_request_ctx,
|
| 524 | u.streamcipher_req) +
|
| 525 | crypto_skcipher_reqsize(streamcipher)));
|
| 526 | return 0;
|
| 527 |
|
| 528 | err_free_streamcipher:
|
| 529 | crypto_free_skcipher(streamcipher);
|
| 530 | return err;
|
| 531 | }
|
| 532 |
|
| 533 | static void adiantum_exit_tfm(struct crypto_skcipher *tfm)
|
| 534 | {
|
| 535 | struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
|
| 536 |
|
| 537 | crypto_free_skcipher(tctx->streamcipher);
|
| 538 | crypto_free_cipher(tctx->blockcipher);
|
| 539 | }
|
| 540 |
|
| 541 | static void adiantum_free_instance(struct skcipher_instance *inst)
|
| 542 | {
|
| 543 | struct adiantum_instance_ctx *ictx = skcipher_instance_ctx(inst);
|
| 544 |
|
| 545 | crypto_drop_skcipher(&ictx->streamcipher_spawn);
|
| 546 | crypto_drop_cipher(&ictx->blockcipher_spawn);
|
| 547 | kfree(inst);
|
| 548 | }
|
| 549 |
|
| 550 | |
| 551 | * Check for a supported set of inner algorithms.
|
| 552 | * See the comment at the beginning of this file.
|
| 553 |
|
| 554 | static bool
|
| 555 | adiantum_supported_algorithms(struct skcipher_alg_common *streamcipher_alg,
|
| 556 | struct crypto_alg *blockcipher_alg)
|
| 557 | {
|
| 558 | if (strcmp(streamcipher_alg->base.cra_name, "xchacha12") != 0 &&
|
| 559 | strcmp(streamcipher_alg->base.cra_name, "xchacha20") != 0)
|
| 560 | return false;
|
| 561 |
|
| 562 | if (blockcipher_alg->cra_cipher.cia_min_keysize > BLOCKCIPHER_KEY_SIZE ||
|
| 563 | blockcipher_alg->cra_cipher.cia_max_keysize < BLOCKCIPHER_KEY_SIZE)
|
| 564 | return false;
|
| 565 | if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
|
| 566 | return false;
|
| 567 |
|
| 568 | return true;
|
| 569 | }
|
| 570 |
|
| 571 | static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
|
| 572 | {
|
| 573 | u32 mask;
|
| 574 | struct skcipher_instance *inst;
|
| 575 | struct adiantum_instance_ctx *ictx;
|
| 576 | struct skcipher_alg_common *streamcipher_alg;
|
| 577 | struct crypto_alg *blockcipher_alg;
|
| 578 | int err;
|
| 579 |
|
| 580 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
|
| 581 | if (err)
|
| 582 | return err;
|
| 583 |
|
| 584 | inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
|
| 585 | if (!inst)
|
| 586 | return -ENOMEM;
|
| 587 | ictx = skcipher_instance_ctx(inst);
|
| 588 |
|
| 589 |
|
| 590 | err = crypto_grab_skcipher(&ictx->streamcipher_spawn,
|
| 591 | skcipher_crypto_instance(inst),
|
| 592 | crypto_attr_alg_name(tb[1]), 0,
|
| 593 | mask | CRYPTO_ALG_ASYNC );
|
| 594 | if (err)
|
| 595 | goto err_free_inst;
|
| 596 | streamcipher_alg = crypto_spawn_skcipher_alg_common(&ictx->streamcipher_spawn);
|
| 597 |
|
| 598 |
|
| 599 | err = crypto_grab_cipher(&ictx->blockcipher_spawn,
|
| 600 | skcipher_crypto_instance(inst),
|
| 601 | crypto_attr_alg_name(tb[2]), 0, mask);
|
| 602 | if (err)
|
| 603 | goto err_free_inst;
|
| 604 | blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
|
| 605 |
|
| 606 | |
| 607 | * Originally there was an optional third parameter, for requesting a
|
| 608 | * specific implementation of "nhpoly1305" for message hashing. This is
|
| 609 | * no longer supported. The best implementation is just always used.
|
| 610 |
|
| 611 | if (crypto_attr_alg_name(tb[3]) != ERR_PTR(-ENOENT)) {
|
| 612 | err = -ENOENT;
|
| 613 | goto err_free_inst;
|
| 614 | }
|
| 615 |
|
| 616 |
|
| 617 | if (!adiantum_supported_algorithms(streamcipher_alg, blockcipher_alg)) {
|
| 618 | pr_warn("Unsupported Adiantum instantiation: (%s,%s)\n",
|
| 619 | streamcipher_alg->base.cra_name,
|
| 620 | blockcipher_alg->cra_name);
|
| 621 | err = -EINVAL;
|
| 622 | goto err_free_inst;
|
| 623 | }
|
| 624 |
|
| 625 |
|
| 626 |
|
| 627 | err = -ENAMETOOLONG;
|
| 628 | if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
|
| 629 | "adiantum(%s,%s)", streamcipher_alg->base.cra_name,
|
| 630 | blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
|
| 631 | goto err_free_inst;
|
| 632 | if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
|
| 633 | "adiantum(%s,%s)", streamcipher_alg->base.cra_driver_name,
|
| 634 | blockcipher_alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
|
| 635 | goto err_free_inst;
|
| 636 |
|
| 637 | inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
|
| 638 | inst->alg.base.cra_ctxsize = sizeof(struct adiantum_tfm_ctx);
|
| 639 | inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask;
|
| 640 | |
| 641 | * The block cipher is only invoked once per message, so for long
|
| 642 | * messages (e.g. sectors for disk encryption) its performance doesn't
|
| 643 | * matter as much as that of the stream cipher. Thus, weigh the block
|
| 644 | * cipher's ->cra_priority less.
|
| 645 |
|
| 646 | inst->alg.base.cra_priority = (4 * streamcipher_alg->base.cra_priority +
|
| 647 | blockcipher_alg->cra_priority) /
|
| 648 | 5;
|
| 649 |
|
| 650 | inst->alg.setkey = adiantum_setkey;
|
| 651 | inst->alg.encrypt = adiantum_encrypt;
|
| 652 | inst->alg.decrypt = adiantum_decrypt;
|
| 653 | inst->alg.init = adiantum_init_tfm;
|
| 654 | inst->alg.exit = adiantum_exit_tfm;
|
| 655 | inst->alg.min_keysize = streamcipher_alg->min_keysize;
|
| 656 | inst->alg.max_keysize = streamcipher_alg->max_keysize;
|
| 657 | inst->alg.ivsize = TWEAK_SIZE;
|
| 658 |
|
| 659 | inst->free = adiantum_free_instance;
|
| 660 |
|
| 661 | err = skcipher_register_instance(tmpl, inst);
|
| 662 | if (err) {
|
| 663 | err_free_inst:
|
| 664 | adiantum_free_instance(inst);
|
| 665 | }
|
| 666 | return err;
|
| 667 | }
|
| 668 |
|
| 669 |
|
| 670 | static struct crypto_template adiantum_tmpl = {
|
| 671 | .name = "adiantum",
|
| 672 | .create = adiantum_create,
|
| 673 | .module = THIS_MODULE,
|
| 674 | };
|
| 675 |
|
| 676 | static int __init adiantum_module_init(void)
|
| 677 | {
|
| 678 | return crypto_register_template(&adiantum_tmpl);
|
| 679 | }
|
| 680 |
|
| 681 | static void __exit adiantum_module_exit(void)
|
| 682 | {
|
| 683 | crypto_unregister_template(&adiantum_tmpl);
|
| 684 | }
|
| 685 |
|
| 686 | module_init(adiantum_module_init);
|
| 687 | module_exit(adiantum_module_exit);
|
| 688 |
|
| 689 | MODULE_DESCRIPTION("Adiantum length-preserving encryption mode");
|
| 690 | MODULE_LICENSE("GPL v2");
|
| 691 | MODULE_AUTHOR("Eric Biggers <[email protected]>");
|
| 692 | MODULE_ALIAS_CRYPTO("adiantum");
|
| 693 | MODULE_IMPORT_NS("CRYPTO_INTERNAL");
|