Changeset View
Changeset View
Standalone View
Standalone View
sys/crypto/armv8/armv8_crypto.c
Show First 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | armv8_crypto_probe(device_t dev) | ||||
switch (ID_AA64ISAR0_AES_VAL(reg)) { | switch (ID_AA64ISAR0_AES_VAL(reg)) { | ||||
case ID_AA64ISAR0_AES_BASE: | case ID_AA64ISAR0_AES_BASE: | ||||
case ID_AA64ISAR0_AES_PMULL: | case ID_AA64ISAR0_AES_PMULL: | ||||
ret = 0; | ret = 0; | ||||
break; | break; | ||||
} | } | ||||
device_set_desc_copy(dev, "AES-CBC"); | device_set_desc_copy(dev, "AES-CBC,AES-XTS"); | ||||
/* TODO: Check more fields as we support more features */ | /* TODO: Check more fields as we support more features */ | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static int | static int | ||||
armv8_crypto_attach(device_t dev) | armv8_crypto_attach(device_t dev) | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | armv8_crypto_detach(device_t dev) | ||||
ctx_vfp = NULL; | ctx_vfp = NULL; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
armv8_crypto_probesession(device_t dev, | armv8_crypto_probesession(device_t dev, | ||||
const struct crypto_session_params *csp) | const struct crypto_session_params *csp) | ||||
{ | { | ||||
manu: Why did you change the argument here ?
You have the key and the key length in the struct… | |||||
Done Inline ActionsLook at the calls — in the CRD_F_KEY_EXPLICIT case, instead of cryptoini, we have cryptodesc. This is how aesni deals with this. val_packett.cool: Look at the calls — in the `CRD_F_KEY_EXPLICIT` case, instead of `cryptoini`, we have… | |||||
if (csp->csp_flags != 0) | if (csp->csp_flags != 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
switch (csp->csp_mode) { | switch (csp->csp_mode) { | ||||
case CSP_MODE_CIPHER: | case CSP_MODE_CIPHER: | ||||
switch (csp->csp_cipher_alg) { | switch (csp->csp_cipher_alg) { | ||||
case CRYPTO_AES_CBC: | case CRYPTO_AES_CBC: | ||||
if (csp->csp_ivlen != AES_BLOCK_LEN) | if (csp->csp_ivlen != AES_BLOCK_LEN) | ||||
return (EINVAL); | return (EINVAL); | ||||
switch (csp->csp_cipher_klen * 8) { | switch (csp->csp_cipher_klen * 8) { | ||||
case 128: | case 128: | ||||
case 192: | case 192: | ||||
case 256: | case 256: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
break; | break; | ||||
case CRYPTO_AES_XTS: | |||||
if (csp->csp_ivlen != AES_XTS_IV_LEN) | |||||
return (EINVAL); | |||||
switch (csp->csp_cipher_klen * 8) { | |||||
case 256: | |||||
case 512: | |||||
break; | |||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
break; | |||||
default: | |||||
return (EINVAL); | |||||
} | |||||
return (CRYPTODEV_PROBE_ACCEL_SOFTWARE); | return (CRYPTODEV_PROBE_ACCEL_SOFTWARE); | ||||
} | } | ||||
static void | static void | ||||
armv8_crypto_cipher_setup(struct armv8_crypto_session *ses, | armv8_crypto_cipher_setup(struct armv8_crypto_session *ses, | ||||
const struct crypto_session_params *csp) | const struct crypto_session_params *csp, const uint8_t *key, int keylen) | ||||
{ | { | ||||
int i; | int i; | ||||
switch (csp->csp_cipher_klen * 8) { | if (csp->csp_cipher_alg == CRYPTO_AES_XTS) | ||||
keylen /= 2; | |||||
switch (keylen * 8) { | |||||
case 128: | case 128: | ||||
ses->rounds = AES128_ROUNDS; | ses->rounds = AES128_ROUNDS; | ||||
break; | break; | ||||
case 192: | case 192: | ||||
ses->rounds = AES192_ROUNDS; | ses->rounds = AES192_ROUNDS; | ||||
break; | break; | ||||
case 256: | case 256: | ||||
ses->rounds = AES256_ROUNDS; | ses->rounds = AES256_ROUNDS; | ||||
break; | break; | ||||
default: | default: | ||||
panic("invalid CBC key length"); | panic("invalid AES key length"); | ||||
} | } | ||||
rijndaelKeySetupEnc(ses->enc_schedule, csp->csp_cipher_key, | rijndaelKeySetupEnc(ses->enc_schedule, key, keylen * 8); | ||||
csp->csp_cipher_klen * 8); | rijndaelKeySetupDec(ses->dec_schedule, key, keylen * 8); | ||||
rijndaelKeySetupDec(ses->dec_schedule, csp->csp_cipher_key, | if (csp->csp_cipher_alg == CRYPTO_AES_XTS) | ||||
csp->csp_cipher_klen * 8); | rijndaelKeySetupEnc(ses->xts_schedule, key + keylen, keylen * 8); | ||||
for (i = 0; i < nitems(ses->enc_schedule); i++) { | for (i = 0; i < nitems(ses->enc_schedule); i++) { | ||||
ses->enc_schedule[i] = bswap32(ses->enc_schedule[i]); | ses->enc_schedule[i] = bswap32(ses->enc_schedule[i]); | ||||
ses->dec_schedule[i] = bswap32(ses->dec_schedule[i]); | ses->dec_schedule[i] = bswap32(ses->dec_schedule[i]); | ||||
if (csp->csp_cipher_alg == CRYPTO_AES_XTS) | |||||
ses->xts_schedule[i] = bswap32(ses->xts_schedule[i]); | |||||
} | } | ||||
} | } | ||||
static int | static int | ||||
armv8_crypto_newsession(device_t dev, crypto_session_t cses, | armv8_crypto_newsession(device_t dev, crypto_session_t cses, | ||||
const struct crypto_session_params *csp) | const struct crypto_session_params *csp) | ||||
{ | { | ||||
struct armv8_crypto_softc *sc; | struct armv8_crypto_softc *sc; | ||||
struct armv8_crypto_session *ses; | struct armv8_crypto_session *ses; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
rw_wlock(&sc->lock); | rw_wlock(&sc->lock); | ||||
if (sc->dieing) { | if (sc->dieing) { | ||||
rw_wunlock(&sc->lock); | rw_wunlock(&sc->lock); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
ses = crypto_get_driver_session(cses); | ses = crypto_get_driver_session(cses); | ||||
armv8_crypto_cipher_setup(ses, csp); | armv8_crypto_cipher_setup(ses, csp, csp->csp_cipher_key, | ||||
csp->csp_cipher_klen); | |||||
rw_wunlock(&sc->lock); | rw_wunlock(&sc->lock); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
armv8_crypto_process(device_t dev, struct cryptop *crp, int hint __unused) | armv8_crypto_process(device_t dev, struct cryptop *crp, int hint __unused) | ||||
{ | { | ||||
struct armv8_crypto_session *ses; | struct armv8_crypto_session *ses; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | armv8_crypto_cipher_process(struct armv8_crypto_session *ses, | ||||
kt = is_fpu_kern_thread(0); | kt = is_fpu_kern_thread(0); | ||||
if (!kt) { | if (!kt) { | ||||
AQUIRE_CTX(i, ctx); | AQUIRE_CTX(i, ctx); | ||||
fpu_kern_enter(curthread, ctx, | fpu_kern_enter(curthread, ctx, | ||||
FPU_KERN_NORMAL | FPU_KERN_KTHR); | FPU_KERN_NORMAL | FPU_KERN_KTHR); | ||||
} | } | ||||
if (crp->crp_cipher_key != NULL) { | if (crp->crp_cipher_key != NULL) { | ||||
panic("armv8: new cipher key"); | armv8_crypto_cipher_setup(ses, csp, crp->crp_cipher_key, | ||||
csp->csp_cipher_klen); | |||||
} | } | ||||
crypto_read_iv(crp, iv); | crypto_read_iv(crp, iv); | ||||
/* Do work */ | /* Do work */ | ||||
switch (csp->csp_cipher_alg) { | switch (csp->csp_cipher_alg) { | ||||
case CRYPTO_AES_CBC: | case CRYPTO_AES_CBC: | ||||
if (encflag) | if (encflag) | ||||
armv8_aes_encrypt_cbc(ses->rounds, ses->enc_schedule, | armv8_aes_encrypt_cbc(ses->rounds, ses->enc_schedule, | ||||
crp->crp_payload_length, buf, buf, iv); | crp->crp_payload_length, buf, buf, iv); | ||||
else | else | ||||
armv8_aes_decrypt_cbc(ses->rounds, ses->dec_schedule, | armv8_aes_decrypt_cbc(ses->rounds, ses->dec_schedule, | ||||
crp->crp_payload_length, buf, iv); | crp->crp_payload_length, buf, iv); | ||||
break; | |||||
case CRYPTO_AES_XTS: | |||||
if (encflag) | |||||
armv8_aes_encrypt_xts(ses->rounds, ses->enc_schedule, | |||||
ses->xts_schedule, crp->crp_payload_length, buf, | |||||
buf, iv); | |||||
else | |||||
armv8_aes_decrypt_xts(ses->rounds, ses->dec_schedule, | |||||
ses->xts_schedule, crp->crp_payload_length, buf, | |||||
buf, iv); | |||||
break; | break; | ||||
} | } | ||||
if (allocated) | if (allocated) | ||||
crypto_copyback(crp, crp->crp_payload_start, | crypto_copyback(crp, crp->crp_payload_start, | ||||
crp->crp_payload_length, buf); | crp->crp_payload_length, buf); | ||||
if (!kt) { | if (!kt) { | ||||
Show All 27 Lines |
Why did you change the argument here ?
You have the key and the key length in the struct cryptoini