Deleted Added
full compact
28c28
< __FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_crypto.c 275732 2014-12-12 19:56:36Z jmg $");
---
> __FBSDID("$FreeBSD: head/sys/geom/eli/g_eli_hmac.c 293306 2016-01-07 05:47:34Z allanjude $");
46,224d45
< #ifdef _KERNEL
< MALLOC_DECLARE(M_ELI);
<
< static int
< g_eli_crypto_done(struct cryptop *crp)
< {
<
< crp->crp_opaque = (void *)crp;
< wakeup(crp);
< return (0);
< }
<
< static int
< g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
< const u_char *key, size_t keysize)
< {
< struct cryptoini cri;
< struct cryptop *crp;
< struct cryptodesc *crd;
< uint64_t sid;
< u_char *p;
< int error;
<
< KASSERT(algo != CRYPTO_AES_XTS,
< ("%s: CRYPTO_AES_XTS unexpected here", __func__));
<
< bzero(&cri, sizeof(cri));
< cri.cri_alg = algo;
< cri.cri_key = __DECONST(void *, key);
< cri.cri_klen = keysize;
< error = crypto_newsession(&sid, &cri, CRYPTOCAP_F_SOFTWARE);
< if (error != 0)
< return (error);
< p = malloc(sizeof(*crp) + sizeof(*crd), M_ELI, M_NOWAIT | M_ZERO);
< if (p == NULL) {
< crypto_freesession(sid);
< return (ENOMEM);
< }
< crp = (struct cryptop *)p; p += sizeof(*crp);
< crd = (struct cryptodesc *)p; p += sizeof(*crd);
<
< crd->crd_skip = 0;
< crd->crd_len = datasize;
< crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
< if (enc)
< crd->crd_flags |= CRD_F_ENCRYPT;
< crd->crd_alg = algo;
< crd->crd_key = __DECONST(void *, key);
< crd->crd_klen = keysize;
< bzero(crd->crd_iv, sizeof(crd->crd_iv));
< crd->crd_next = NULL;
<
< crp->crp_sid = sid;
< crp->crp_ilen = datasize;
< crp->crp_olen = datasize;
< crp->crp_opaque = NULL;
< crp->crp_callback = g_eli_crypto_done;
< crp->crp_buf = (void *)data;
< crp->crp_flags = CRYPTO_F_CBIFSYNC;
< crp->crp_desc = crd;
<
< error = crypto_dispatch(crp);
< if (error == 0) {
< while (crp->crp_opaque == NULL)
< tsleep(crp, PRIBIO, "geli", hz / 5);
< error = crp->crp_etype;
< }
<
< free(crp, M_ELI);
< crypto_freesession(sid);
< return (error);
< }
< #else /* !_KERNEL */
< static int
< g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
< const u_char *key, size_t keysize)
< {
< EVP_CIPHER_CTX ctx;
< const EVP_CIPHER *type;
< u_char iv[keysize];
< int outsize;
<
< assert(algo != CRYPTO_AES_XTS);
<
< switch (algo) {
< case CRYPTO_NULL_CBC:
< type = EVP_enc_null();
< break;
< case CRYPTO_AES_CBC:
< switch (keysize) {
< case 128:
< type = EVP_aes_128_cbc();
< break;
< case 192:
< type = EVP_aes_192_cbc();
< break;
< case 256:
< type = EVP_aes_256_cbc();
< break;
< default:
< return (EINVAL);
< }
< break;
< case CRYPTO_BLF_CBC:
< type = EVP_bf_cbc();
< break;
< #ifndef OPENSSL_NO_CAMELLIA
< case CRYPTO_CAMELLIA_CBC:
< switch (keysize) {
< case 128:
< type = EVP_camellia_128_cbc();
< break;
< case 192:
< type = EVP_camellia_192_cbc();
< break;
< case 256:
< type = EVP_camellia_256_cbc();
< break;
< default:
< return (EINVAL);
< }
< break;
< #endif
< case CRYPTO_3DES_CBC:
< type = EVP_des_ede3_cbc();
< break;
< default:
< return (EINVAL);
< }
<
< EVP_CIPHER_CTX_init(&ctx);
<
< EVP_CipherInit_ex(&ctx, type, NULL, NULL, NULL, enc);
< EVP_CIPHER_CTX_set_key_length(&ctx, keysize / 8);
< EVP_CIPHER_CTX_set_padding(&ctx, 0);
< bzero(iv, sizeof(iv));
< EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, enc);
<
< if (EVP_CipherUpdate(&ctx, data, &outsize, data, datasize) == 0) {
< EVP_CIPHER_CTX_cleanup(&ctx);
< return (EINVAL);
< }
< assert(outsize == (int)datasize);
<
< if (EVP_CipherFinal_ex(&ctx, data + outsize, &outsize) == 0) {
< EVP_CIPHER_CTX_cleanup(&ctx);
< return (EINVAL);
< }
< assert(outsize == 0);
<
< EVP_CIPHER_CTX_cleanup(&ctx);
< return (0);
< }
< #endif /* !_KERNEL */
<
< int
< g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize,
< const u_char *key, size_t keysize)
< {
<
< /* We prefer AES-CBC for metadata protection. */
< if (algo == CRYPTO_AES_XTS)
< algo = CRYPTO_AES_CBC;
<
< return (g_eli_crypto_cipher(algo, 1, data, datasize, key, keysize));
< }
<
< int
< g_eli_crypto_decrypt(u_int algo, u_char *data, size_t datasize,
< const u_char *key, size_t keysize)
< {
<
< /* We prefer AES-CBC for metadata protection. */
< if (algo == CRYPTO_AES_XTS)
< algo = CRYPTO_AES_CBC;
<
< return (g_eli_crypto_cipher(algo, 0, data, datasize, key, keysize));
< }
<
295a117,150
>
> /*
> * Here we generate IV. It is unique for every sector.
> */
> void
> g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv,
> size_t size)
> {
> uint8_t off[8];
>
> if ((sc->sc_flags & G_ELI_FLAG_NATIVE_BYTE_ORDER) != 0)
> bcopy(&offset, off, sizeof(off));
> else
> le64enc(off, (uint64_t)offset);
>
> switch (sc->sc_ealgo) {
> case CRYPTO_AES_XTS:
> bcopy(off, iv, sizeof(off));
> bzero(iv + sizeof(off), size - sizeof(off));
> break;
> default:
> {
> u_char hash[SHA256_DIGEST_LENGTH];
> SHA256_CTX ctx;
>
> /* Copy precalculated SHA256 context for IV-Key. */
> bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx));
> SHA256_Update(&ctx, off, sizeof(off));
> SHA256_Final(hash, &ctx);
> bcopy(hash, iv, MIN(sizeof(hash), size));
> break;
> }
> }
> }