Ejemplo n.º 1
0
static int crypto_gcm_decrypt(struct aead_request *req)
{
    struct crypto_aead *aead = crypto_aead_reqtfm(req);
    struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
    struct ablkcipher_request *abreq = &pctx->u.abreq;
    struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
    unsigned int authsize = crypto_aead_authsize(aead);
    unsigned int cryptlen = req->cryptlen;
    int err;

    if (cryptlen < authsize)
        return -EINVAL;
    cryptlen -= authsize;

    gctx->src = req->src;
    gctx->cryptlen = cryptlen;
    gctx->complete = gcm_dec_hash_done;

    err = gcm_hash(req, pctx);
    if (err)
        return err;

    ablkcipher_request_set_callback(abreq, aead_request_flags(req),
                                    gcm_decrypt_done, req);
    crypto_gcm_init_crypt(abreq, req, cryptlen);
    err = crypto_ablkcipher_decrypt(abreq);
    if (err)
        return err;

    return crypto_gcm_verify(req, pctx);
}
Ejemplo n.º 2
0
static int crypto_gcm_encrypt(struct aead_request *req)
{
    struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
    struct ablkcipher_request *abreq = &pctx->u.abreq;
    struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
    int err;

    crypto_gcm_init_crypt(abreq, req, req->cryptlen);
    ablkcipher_request_set_callback(abreq, aead_request_flags(req),
                                    gcm_encrypt_done, req);

    gctx->src = req->dst;
    gctx->cryptlen = req->cryptlen;
    gctx->complete = gcm_enc_hash_done;

    err = crypto_ablkcipher_encrypt(abreq);
    if (err)
        return err;

    err = gcm_hash(req, pctx);
    if (err)
        return err;

    crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
    gcm_enc_copy_hash(req, pctx);

    return 0;
}
Ejemplo n.º 3
0
static int crypto_gcm_decrypt(struct aead_request *req)
{
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct ablkcipher_request *abreq = &pctx->abreq;
	struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
	unsigned int cryptlen = req->cryptlen;
	unsigned int authsize = crypto_aead_authsize(aead);
	int err;

	if (cryptlen < authsize)
		return -EINVAL;
	cryptlen -= authsize;

	crypto_gcm_init_crypt(abreq, req, cryptlen);
	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
					crypto_gcm_decrypt_done, req);

	crypto_gcm_ghash_update_sg(ghash, req->src, cryptlen);

	err = crypto_ablkcipher_decrypt(abreq);
	if (err)
		return err;

	return crypto_gcm_verify(req);
}
Ejemplo n.º 4
0
static int crypto_gcm_encrypt(struct aead_request *req)
{
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct ablkcipher_request *abreq = &pctx->abreq;
	int err;

	crypto_gcm_init_crypt(abreq, req, req->cryptlen);
	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
					crypto_gcm_encrypt_done, req);

	err = crypto_ablkcipher_encrypt(abreq);
	if (err)
		return err;

	return crypto_gcm_hash(req);
}
Ejemplo n.º 5
0
static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
{
	struct aead_request *req = areq->data;
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct ablkcipher_request *abreq = &pctx->u.abreq;
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;

	if (!err) {
		ablkcipher_request_set_callback(abreq, aead_request_flags(req),
						gcm_decrypt_done, req);
		crypto_gcm_init_crypt(abreq, req, gctx->cryptlen);
		err = crypto_ablkcipher_decrypt(abreq);
		if (err == -EINPROGRESS || err == -EBUSY)
			return;
	}

	gcm_decrypt_done(areq, err);
}