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 */ 77