Add support for AES-XTS.
Obtained from: OpenBSD MFC after: 1 week
This commit is contained in:
parent
c6a26d4c88
commit
d295bdee07
@ -419,6 +419,9 @@ cryptof_ioctl(
|
|||||||
case CRYPTO_AES_CBC:
|
case CRYPTO_AES_CBC:
|
||||||
txform = &enc_xform_rijndael128;
|
txform = &enc_xform_rijndael128;
|
||||||
break;
|
break;
|
||||||
|
case CRYPTO_AES_XTS:
|
||||||
|
txform = &enc_xform_aes_xts;
|
||||||
|
break;
|
||||||
case CRYPTO_NULL_CBC:
|
case CRYPTO_NULL_CBC:
|
||||||
txform = &enc_xform_null;
|
txform = &enc_xform_null;
|
||||||
break;
|
break;
|
||||||
|
@ -123,7 +123,8 @@
|
|||||||
#define CRYPTO_SHA2_384_HMAC 19
|
#define CRYPTO_SHA2_384_HMAC 19
|
||||||
#define CRYPTO_SHA2_512_HMAC 20
|
#define CRYPTO_SHA2_512_HMAC 20
|
||||||
#define CRYPTO_CAMELLIA_CBC 21
|
#define CRYPTO_CAMELLIA_CBC 21
|
||||||
#define CRYPTO_ALGORITHM_MAX 21 /* Keep updated - see below */
|
#define CRYPTO_AES_XTS 22
|
||||||
|
#define CRYPTO_ALGORITHM_MAX 22 /* Keep updated - see below */
|
||||||
|
|
||||||
/* Algorithm flags */
|
/* Algorithm flags */
|
||||||
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
|
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
|
||||||
|
@ -114,8 +114,16 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
ivp = iv;
|
ivp = iv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xforms that provide a reinit method perform all IV
|
||||||
|
* handling themselves.
|
||||||
|
*/
|
||||||
|
if (exf->reinit)
|
||||||
|
exf->reinit(sw->sw_kschedule, iv);
|
||||||
|
|
||||||
if (flags & CRYPTO_F_IMBUF) {
|
if (flags & CRYPTO_F_IMBUF) {
|
||||||
struct mbuf *m = (struct mbuf *) buf;
|
struct mbuf *m = (struct mbuf *) buf;
|
||||||
|
|
||||||
@ -135,7 +143,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
m_copydata(m, k, blks, blk);
|
m_copydata(m, k, blks, blk);
|
||||||
|
|
||||||
/* Actual encryption/decryption */
|
/* Actual encryption/decryption */
|
||||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
if (exf->reinit) {
|
||||||
|
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
|
exf->encrypt(sw->sw_kschedule,
|
||||||
|
blk);
|
||||||
|
} else {
|
||||||
|
exf->decrypt(sw->sw_kschedule,
|
||||||
|
blk);
|
||||||
|
}
|
||||||
|
} else if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
/* XOR with previous block */
|
/* XOR with previous block */
|
||||||
for (j = 0; j < blks; j++)
|
for (j = 0; j < blks; j++)
|
||||||
blk[j] ^= ivp[j];
|
blk[j] ^= ivp[j];
|
||||||
@ -205,7 +221,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
idat = mtod(m, unsigned char *) + k;
|
idat = mtod(m, unsigned char *) + k;
|
||||||
|
|
||||||
while (m->m_len >= k + blks && i > 0) {
|
while (m->m_len >= k + blks && i > 0) {
|
||||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
if (exf->reinit) {
|
||||||
|
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
|
exf->encrypt(sw->sw_kschedule,
|
||||||
|
idat);
|
||||||
|
} else {
|
||||||
|
exf->decrypt(sw->sw_kschedule,
|
||||||
|
idat);
|
||||||
|
}
|
||||||
|
} else if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
/* XOR with previous block/IV */
|
/* XOR with previous block/IV */
|
||||||
for (j = 0; j < blks; j++)
|
for (j = 0; j < blks; j++)
|
||||||
idat[j] ^= ivp[j];
|
idat[j] ^= ivp[j];
|
||||||
@ -261,7 +285,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
cuio_copydata(uio, k, blks, blk);
|
cuio_copydata(uio, k, blks, blk);
|
||||||
|
|
||||||
/* Actual encryption/decryption */
|
/* Actual encryption/decryption */
|
||||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
if (exf->reinit) {
|
||||||
|
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
|
exf->encrypt(sw->sw_kschedule,
|
||||||
|
blk);
|
||||||
|
} else {
|
||||||
|
exf->decrypt(sw->sw_kschedule,
|
||||||
|
blk);
|
||||||
|
}
|
||||||
|
} else if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
/* XOR with previous block */
|
/* XOR with previous block */
|
||||||
for (j = 0; j < blks; j++)
|
for (j = 0; j < blks; j++)
|
||||||
blk[j] ^= ivp[j];
|
blk[j] ^= ivp[j];
|
||||||
@ -319,7 +351,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
idat = (char *)iov->iov_base + k;
|
idat = (char *)iov->iov_base + k;
|
||||||
|
|
||||||
while (iov->iov_len >= k + blks && i > 0) {
|
while (iov->iov_len >= k + blks && i > 0) {
|
||||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
if (exf->reinit) {
|
||||||
|
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
|
exf->encrypt(sw->sw_kschedule,
|
||||||
|
idat);
|
||||||
|
} else {
|
||||||
|
exf->decrypt(sw->sw_kschedule,
|
||||||
|
idat);
|
||||||
|
}
|
||||||
|
} else if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
/* XOR with previous block/IV */
|
/* XOR with previous block/IV */
|
||||||
for (j = 0; j < blks; j++)
|
for (j = 0; j < blks; j++)
|
||||||
idat[j] ^= ivp[j];
|
idat[j] ^= ivp[j];
|
||||||
@ -360,7 +400,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
|
|||||||
|
|
||||||
return 0; /* Done with iovec encryption/decryption */
|
return 0; /* Done with iovec encryption/decryption */
|
||||||
} else { /* contiguous buffer */
|
} else { /* contiguous buffer */
|
||||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
if (exf->reinit) {
|
||||||
|
for (i = crd->crd_skip;
|
||||||
|
i < crd->crd_skip + crd->crd_len; i += blks) {
|
||||||
|
if (crd->crd_flags & CRD_F_ENCRYPT)
|
||||||
|
exf->encrypt(sw->sw_kschedule, buf + i);
|
||||||
|
else
|
||||||
|
exf->decrypt(sw->sw_kschedule, buf + i);
|
||||||
|
}
|
||||||
|
} else if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||||
for (i = crd->crd_skip;
|
for (i = crd->crd_skip;
|
||||||
i < crd->crd_skip + crd->crd_len; i += blks) {
|
i < crd->crd_skip + crd->crd_len; i += blks) {
|
||||||
/* XOR with the IV/previous block, as appropriate. */
|
/* XOR with the IV/previous block, as appropriate. */
|
||||||
@ -687,6 +735,9 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
|
|||||||
case CRYPTO_RIJNDAEL128_CBC:
|
case CRYPTO_RIJNDAEL128_CBC:
|
||||||
txf = &enc_xform_rijndael128;
|
txf = &enc_xform_rijndael128;
|
||||||
goto enccommon;
|
goto enccommon;
|
||||||
|
case CRYPTO_AES_XTS:
|
||||||
|
txf = &enc_xform_aes_xts;
|
||||||
|
goto enccommon;
|
||||||
case CRYPTO_CAMELLIA_CBC:
|
case CRYPTO_CAMELLIA_CBC:
|
||||||
txf = &enc_xform_camellia;
|
txf = &enc_xform_camellia;
|
||||||
goto enccommon;
|
goto enccommon;
|
||||||
@ -845,6 +896,7 @@ swcr_freesession(device_t dev, u_int64_t tid)
|
|||||||
case CRYPTO_CAST_CBC:
|
case CRYPTO_CAST_CBC:
|
||||||
case CRYPTO_SKIPJACK_CBC:
|
case CRYPTO_SKIPJACK_CBC:
|
||||||
case CRYPTO_RIJNDAEL128_CBC:
|
case CRYPTO_RIJNDAEL128_CBC:
|
||||||
|
case CRYPTO_AES_XTS:
|
||||||
case CRYPTO_CAMELLIA_CBC:
|
case CRYPTO_CAMELLIA_CBC:
|
||||||
case CRYPTO_NULL_CBC:
|
case CRYPTO_NULL_CBC:
|
||||||
txf = swd->sw_exf;
|
txf = swd->sw_exf;
|
||||||
@ -958,6 +1010,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
|
|||||||
case CRYPTO_CAST_CBC:
|
case CRYPTO_CAST_CBC:
|
||||||
case CRYPTO_SKIPJACK_CBC:
|
case CRYPTO_SKIPJACK_CBC:
|
||||||
case CRYPTO_RIJNDAEL128_CBC:
|
case CRYPTO_RIJNDAEL128_CBC:
|
||||||
|
case CRYPTO_AES_XTS:
|
||||||
case CRYPTO_CAMELLIA_CBC:
|
case CRYPTO_CAMELLIA_CBC:
|
||||||
if ((crp->crp_etype = swcr_encdec(crd, sw,
|
if ((crp->crp_etype = swcr_encdec(crd, sw,
|
||||||
crp->crp_buf, crp->crp_flags)) != 0)
|
crp->crp_buf, crp->crp_flags)) != 0)
|
||||||
@ -1050,6 +1103,7 @@ swcr_attach(device_t dev)
|
|||||||
REGISTER(CRYPTO_MD5);
|
REGISTER(CRYPTO_MD5);
|
||||||
REGISTER(CRYPTO_SHA1);
|
REGISTER(CRYPTO_SHA1);
|
||||||
REGISTER(CRYPTO_RIJNDAEL128_CBC);
|
REGISTER(CRYPTO_RIJNDAEL128_CBC);
|
||||||
|
REGISTER(CRYPTO_AES_XTS);
|
||||||
REGISTER(CRYPTO_CAMELLIA_CBC);
|
REGISTER(CRYPTO_CAMELLIA_CBC);
|
||||||
REGISTER(CRYPTO_DEFLATE_COMP);
|
REGISTER(CRYPTO_DEFLATE_COMP);
|
||||||
#undef REGISTER
|
#undef REGISTER
|
||||||
|
@ -64,40 +64,48 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <opencrypto/cryptodev.h>
|
#include <opencrypto/cryptodev.h>
|
||||||
#include <opencrypto/xform.h>
|
#include <opencrypto/xform.h>
|
||||||
|
|
||||||
static void null_encrypt(caddr_t, u_int8_t *);
|
static int null_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static void null_decrypt(caddr_t, u_int8_t *);
|
|
||||||
static int null_setkey(u_int8_t **, u_int8_t *, int);
|
|
||||||
static void null_zerokey(u_int8_t **);
|
|
||||||
|
|
||||||
static int des1_setkey(u_int8_t **, u_int8_t *, int);
|
static int des1_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int des3_setkey(u_int8_t **, u_int8_t *, int);
|
static int des3_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int blf_setkey(u_int8_t **, u_int8_t *, int);
|
static int blf_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
|
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
|
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
|
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
|
static int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
static int cml_setkey(u_int8_t **, u_int8_t *, int);
|
static int cml_setkey(u_int8_t **, u_int8_t *, int);
|
||||||
|
|
||||||
|
static void null_encrypt(caddr_t, u_int8_t *);
|
||||||
static void des1_encrypt(caddr_t, u_int8_t *);
|
static void des1_encrypt(caddr_t, u_int8_t *);
|
||||||
static void des3_encrypt(caddr_t, u_int8_t *);
|
static void des3_encrypt(caddr_t, u_int8_t *);
|
||||||
static void blf_encrypt(caddr_t, u_int8_t *);
|
static void blf_encrypt(caddr_t, u_int8_t *);
|
||||||
static void cast5_encrypt(caddr_t, u_int8_t *);
|
static void cast5_encrypt(caddr_t, u_int8_t *);
|
||||||
static void skipjack_encrypt(caddr_t, u_int8_t *);
|
static void skipjack_encrypt(caddr_t, u_int8_t *);
|
||||||
static void rijndael128_encrypt(caddr_t, u_int8_t *);
|
static void rijndael128_encrypt(caddr_t, u_int8_t *);
|
||||||
|
static void aes_xts_encrypt(caddr_t, u_int8_t *);
|
||||||
static void cml_encrypt(caddr_t, u_int8_t *);
|
static void cml_encrypt(caddr_t, u_int8_t *);
|
||||||
|
|
||||||
|
static void null_decrypt(caddr_t, u_int8_t *);
|
||||||
static void des1_decrypt(caddr_t, u_int8_t *);
|
static void des1_decrypt(caddr_t, u_int8_t *);
|
||||||
static void des3_decrypt(caddr_t, u_int8_t *);
|
static void des3_decrypt(caddr_t, u_int8_t *);
|
||||||
static void blf_decrypt(caddr_t, u_int8_t *);
|
static void blf_decrypt(caddr_t, u_int8_t *);
|
||||||
static void cast5_decrypt(caddr_t, u_int8_t *);
|
static void cast5_decrypt(caddr_t, u_int8_t *);
|
||||||
static void skipjack_decrypt(caddr_t, u_int8_t *);
|
static void skipjack_decrypt(caddr_t, u_int8_t *);
|
||||||
static void rijndael128_decrypt(caddr_t, u_int8_t *);
|
static void rijndael128_decrypt(caddr_t, u_int8_t *);
|
||||||
|
static void aes_xts_decrypt(caddr_t, u_int8_t *);
|
||||||
static void cml_decrypt(caddr_t, u_int8_t *);
|
static void cml_decrypt(caddr_t, u_int8_t *);
|
||||||
|
|
||||||
|
static void null_zerokey(u_int8_t **);
|
||||||
static void des1_zerokey(u_int8_t **);
|
static void des1_zerokey(u_int8_t **);
|
||||||
static void des3_zerokey(u_int8_t **);
|
static void des3_zerokey(u_int8_t **);
|
||||||
static void blf_zerokey(u_int8_t **);
|
static void blf_zerokey(u_int8_t **);
|
||||||
static void cast5_zerokey(u_int8_t **);
|
static void cast5_zerokey(u_int8_t **);
|
||||||
static void skipjack_zerokey(u_int8_t **);
|
static void skipjack_zerokey(u_int8_t **);
|
||||||
static void rijndael128_zerokey(u_int8_t **);
|
static void rijndael128_zerokey(u_int8_t **);
|
||||||
|
static void aes_xts_zerokey(u_int8_t **);
|
||||||
static void cml_zerokey(u_int8_t **);
|
static void cml_zerokey(u_int8_t **);
|
||||||
|
|
||||||
|
static void aes_xts_reinit(caddr_t, u_int8_t *);
|
||||||
|
|
||||||
static void null_init(void *);
|
static void null_init(void *);
|
||||||
static int null_update(void *, u_int8_t *, u_int16_t);
|
static int null_update(void *, u_int8_t *, u_int16_t);
|
||||||
static void null_final(u_int8_t *, void *);
|
static void null_final(u_int8_t *, void *);
|
||||||
@ -124,6 +132,7 @@ struct enc_xform enc_xform_null = {
|
|||||||
null_decrypt,
|
null_decrypt,
|
||||||
null_setkey,
|
null_setkey,
|
||||||
null_zerokey,
|
null_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_des = {
|
struct enc_xform enc_xform_des = {
|
||||||
@ -133,6 +142,7 @@ struct enc_xform enc_xform_des = {
|
|||||||
des1_decrypt,
|
des1_decrypt,
|
||||||
des1_setkey,
|
des1_setkey,
|
||||||
des1_zerokey,
|
des1_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_3des = {
|
struct enc_xform enc_xform_3des = {
|
||||||
@ -141,7 +151,8 @@ struct enc_xform enc_xform_3des = {
|
|||||||
des3_encrypt,
|
des3_encrypt,
|
||||||
des3_decrypt,
|
des3_decrypt,
|
||||||
des3_setkey,
|
des3_setkey,
|
||||||
des3_zerokey
|
des3_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_blf = {
|
struct enc_xform enc_xform_blf = {
|
||||||
@ -150,7 +161,8 @@ struct enc_xform enc_xform_blf = {
|
|||||||
blf_encrypt,
|
blf_encrypt,
|
||||||
blf_decrypt,
|
blf_decrypt,
|
||||||
blf_setkey,
|
blf_setkey,
|
||||||
blf_zerokey
|
blf_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_cast5 = {
|
struct enc_xform enc_xform_cast5 = {
|
||||||
@ -159,7 +171,8 @@ struct enc_xform enc_xform_cast5 = {
|
|||||||
cast5_encrypt,
|
cast5_encrypt,
|
||||||
cast5_decrypt,
|
cast5_decrypt,
|
||||||
cast5_setkey,
|
cast5_setkey,
|
||||||
cast5_zerokey
|
cast5_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_skipjack = {
|
struct enc_xform enc_xform_skipjack = {
|
||||||
@ -168,7 +181,8 @@ struct enc_xform enc_xform_skipjack = {
|
|||||||
skipjack_encrypt,
|
skipjack_encrypt,
|
||||||
skipjack_decrypt,
|
skipjack_decrypt,
|
||||||
skipjack_setkey,
|
skipjack_setkey,
|
||||||
skipjack_zerokey
|
skipjack_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_rijndael128 = {
|
struct enc_xform enc_xform_rijndael128 = {
|
||||||
@ -178,6 +192,17 @@ struct enc_xform enc_xform_rijndael128 = {
|
|||||||
rijndael128_decrypt,
|
rijndael128_decrypt,
|
||||||
rijndael128_setkey,
|
rijndael128_setkey,
|
||||||
rijndael128_zerokey,
|
rijndael128_zerokey,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct enc_xform enc_xform_aes_xts = {
|
||||||
|
CRYPTO_AES_XTS, "AES-XTS",
|
||||||
|
RIJNDAEL128_BLOCK_LEN, 32, 64,
|
||||||
|
aes_xts_encrypt,
|
||||||
|
aes_xts_decrypt,
|
||||||
|
aes_xts_setkey,
|
||||||
|
aes_xts_zerokey,
|
||||||
|
aes_xts_reinit
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_arc4 = {
|
struct enc_xform enc_xform_arc4 = {
|
||||||
@ -187,6 +212,7 @@ struct enc_xform enc_xform_arc4 = {
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct enc_xform enc_xform_camellia = {
|
struct enc_xform enc_xform_camellia = {
|
||||||
@ -196,6 +222,7 @@ struct enc_xform enc_xform_camellia = {
|
|||||||
cml_decrypt,
|
cml_decrypt,
|
||||||
cml_setkey,
|
cml_setkey,
|
||||||
cml_zerokey,
|
cml_zerokey,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Authentication instances */
|
/* Authentication instances */
|
||||||
@ -547,6 +574,107 @@ rijndael128_zerokey(u_int8_t **sched)
|
|||||||
*sched = NULL;
|
*sched = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AES_XTS_BLOCKSIZE 16
|
||||||
|
#define AES_XTS_IVSIZE 8
|
||||||
|
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
|
||||||
|
|
||||||
|
struct aes_xts_ctx {
|
||||||
|
rijndael_ctx key1;
|
||||||
|
rijndael_ctx key2;
|
||||||
|
u_int8_t tweak[AES_XTS_BLOCKSIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
aes_xts_reinit(caddr_t key, u_int8_t *iv)
|
||||||
|
{
|
||||||
|
struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
|
||||||
|
u_int64_t blocknum;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare tweak as E_k2(IV). IV is specified as LE representation
|
||||||
|
* of a 64-bit block number which we allow to be passed in directly.
|
||||||
|
*/
|
||||||
|
bcopy(iv, &blocknum, AES_XTS_IVSIZE);
|
||||||
|
for (i = 0; i < AES_XTS_IVSIZE; i++) {
|
||||||
|
ctx->tweak[i] = blocknum & 0xff;
|
||||||
|
blocknum >>= 8;
|
||||||
|
}
|
||||||
|
/* Last 64 bits of IV are always zero */
|
||||||
|
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
|
||||||
|
|
||||||
|
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
|
||||||
|
{
|
||||||
|
u_int8_t block[AES_XTS_BLOCKSIZE];
|
||||||
|
u_int i, carry_in, carry_out;
|
||||||
|
|
||||||
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||||
|
block[i] = data[i] ^ ctx->tweak[i];
|
||||||
|
|
||||||
|
if (do_encrypt)
|
||||||
|
rijndael_encrypt(&ctx->key1, block, data);
|
||||||
|
else
|
||||||
|
rijndael_decrypt(&ctx->key1, block, data);
|
||||||
|
|
||||||
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
|
||||||
|
data[i] ^= ctx->tweak[i];
|
||||||
|
|
||||||
|
/* Exponentiate tweak */
|
||||||
|
carry_in = 0;
|
||||||
|
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
|
||||||
|
carry_out = ctx->tweak[i] & 0x80;
|
||||||
|
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
|
||||||
|
carry_in = carry_out;
|
||||||
|
}
|
||||||
|
if (carry_in)
|
||||||
|
ctx->tweak[0] ^= AES_XTS_ALPHA;
|
||||||
|
bzero(block, sizeof(block));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
aes_xts_encrypt(caddr_t key, u_int8_t *data)
|
||||||
|
{
|
||||||
|
aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
aes_xts_decrypt(caddr_t key, u_int8_t *data)
|
||||||
|
{
|
||||||
|
aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
|
||||||
|
{
|
||||||
|
struct aes_xts_ctx *ctx;
|
||||||
|
|
||||||
|
if (len != 32 && len != 64)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
|
||||||
|
M_NOWAIT | M_ZERO);
|
||||||
|
if (*sched == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
ctx = (struct aes_xts_ctx *)*sched;
|
||||||
|
|
||||||
|
rijndael_set_key(&ctx->key1, key, len * 4);
|
||||||
|
rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
aes_xts_zerokey(u_int8_t **sched)
|
||||||
|
{
|
||||||
|
bzero(*sched, sizeof(struct aes_xts_ctx));
|
||||||
|
free(*sched, M_CRYPTO_DATA);
|
||||||
|
*sched = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cml_encrypt(caddr_t key, u_int8_t *blk)
|
cml_encrypt(caddr_t key, u_int8_t *blk)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,7 @@ struct enc_xform {
|
|||||||
void (*decrypt) (caddr_t, u_int8_t *);
|
void (*decrypt) (caddr_t, u_int8_t *);
|
||||||
int (*setkey) (u_int8_t **, u_int8_t *, int len);
|
int (*setkey) (u_int8_t **, u_int8_t *, int len);
|
||||||
void (*zerokey) (u_int8_t **);
|
void (*zerokey) (u_int8_t **);
|
||||||
|
void (*reinit) (caddr_t, u_int8_t *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct comp_algo {
|
struct comp_algo {
|
||||||
@ -80,6 +81,7 @@ extern struct enc_xform enc_xform_blf;
|
|||||||
extern struct enc_xform enc_xform_cast5;
|
extern struct enc_xform enc_xform_cast5;
|
||||||
extern struct enc_xform enc_xform_skipjack;
|
extern struct enc_xform enc_xform_skipjack;
|
||||||
extern struct enc_xform enc_xform_rijndael128;
|
extern struct enc_xform enc_xform_rijndael128;
|
||||||
|
extern struct enc_xform enc_xform_aes_xts;
|
||||||
extern struct enc_xform enc_xform_arc4;
|
extern struct enc_xform enc_xform_arc4;
|
||||||
extern struct enc_xform enc_xform_camellia;
|
extern struct enc_xform enc_xform_camellia;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user