c0bde308b28ae6566b6f96046b3a53b9951bec7f
[sfrench/cifs-2.6.git] / include / crypto / xts.h
1 #ifndef _CRYPTO_XTS_H
2 #define _CRYPTO_XTS_H
3
4 #include <crypto/b128ops.h>
5 #include <crypto/internal/skcipher.h>
6 #include <linux/fips.h>
7
8 struct scatterlist;
9 struct blkcipher_desc;
10
11 #define XTS_BLOCK_SIZE 16
12
13 struct xts_crypt_req {
14         le128 *tbuf;
15         unsigned int tbuflen;
16
17         void *tweak_ctx;
18         void (*tweak_fn)(void *ctx, u8* dst, const u8* src);
19         void *crypt_ctx;
20         void (*crypt_fn)(void *ctx, u8 *blks, unsigned int nbytes);
21 };
22
23 #define XTS_TWEAK_CAST(x) ((void (*)(void *, u8*, const u8*))(x))
24
25 int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
26               struct scatterlist *src, unsigned int nbytes,
27               struct xts_crypt_req *req);
28
29 static inline int xts_check_key(struct crypto_tfm *tfm,
30                                 const u8 *key, unsigned int keylen)
31 {
32         u32 *flags = &tfm->crt_flags;
33
34         /*
35          * key consists of keys of equal size concatenated, therefore
36          * the length must be even.
37          */
38         if (keylen % 2) {
39                 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
40                 return -EINVAL;
41         }
42
43         /* ensure that the AES and tweak key are not identical */
44         if (fips_enabled &&
45             !crypto_memneq(key, key + (keylen / 2), keylen / 2)) {
46                 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
47                 return -EINVAL;
48         }
49
50         return 0;
51 }
52
53 static inline int xts_verify_key(struct crypto_skcipher *tfm,
54                                  const u8 *key, unsigned int keylen)
55 {
56         /*
57          * key consists of keys of equal size concatenated, therefore
58          * the length must be even.
59          */
60         if (keylen % 2) {
61                 crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
62                 return -EINVAL;
63         }
64
65         /* ensure that the AES and tweak key are not identical */
66         if ((fips_enabled || crypto_skcipher_get_flags(tfm) &
67                              CRYPTO_TFM_REQ_WEAK_KEY) &&
68             !crypto_memneq(key, key + (keylen / 2), keylen / 2)) {
69                 crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY);
70                 return -EINVAL;
71         }
72
73         return 0;
74 }
75
76 #endif  /* _CRYPTO_XTS_H */