cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aead_api.c (2644B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2003-2004, Instant802 Networks, Inc.
      4 * Copyright 2005-2006, Devicescape Software, Inc.
      5 * Copyright 2014-2015, Qualcomm Atheros, Inc.
      6 *
      7 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/types.h>
     12#include <linux/err.h>
     13#include <linux/scatterlist.h>
     14#include <crypto/aead.h>
     15
     16#include "aead_api.h"
     17
     18int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
     19		 u8 *data, size_t data_len, u8 *mic)
     20{
     21	size_t mic_len = crypto_aead_authsize(tfm);
     22	struct scatterlist sg[3];
     23	struct aead_request *aead_req;
     24	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
     25	u8 *__aad;
     26	int ret;
     27
     28	aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
     29	if (!aead_req)
     30		return -ENOMEM;
     31
     32	__aad = (u8 *)aead_req + reqsize;
     33	memcpy(__aad, aad, aad_len);
     34
     35	sg_init_table(sg, 3);
     36	sg_set_buf(&sg[0], __aad, aad_len);
     37	sg_set_buf(&sg[1], data, data_len);
     38	sg_set_buf(&sg[2], mic, mic_len);
     39
     40	aead_request_set_tfm(aead_req, tfm);
     41	aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
     42	aead_request_set_ad(aead_req, sg[0].length);
     43
     44	ret = crypto_aead_encrypt(aead_req);
     45	kfree_sensitive(aead_req);
     46
     47	return ret;
     48}
     49
     50int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
     51		 u8 *data, size_t data_len, u8 *mic)
     52{
     53	size_t mic_len = crypto_aead_authsize(tfm);
     54	struct scatterlist sg[3];
     55	struct aead_request *aead_req;
     56	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
     57	u8 *__aad;
     58	int err;
     59
     60	if (data_len == 0)
     61		return -EINVAL;
     62
     63	aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
     64	if (!aead_req)
     65		return -ENOMEM;
     66
     67	__aad = (u8 *)aead_req + reqsize;
     68	memcpy(__aad, aad, aad_len);
     69
     70	sg_init_table(sg, 3);
     71	sg_set_buf(&sg[0], __aad, aad_len);
     72	sg_set_buf(&sg[1], data, data_len);
     73	sg_set_buf(&sg[2], mic, mic_len);
     74
     75	aead_request_set_tfm(aead_req, tfm);
     76	aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
     77	aead_request_set_ad(aead_req, sg[0].length);
     78
     79	err = crypto_aead_decrypt(aead_req);
     80	kfree_sensitive(aead_req);
     81
     82	return err;
     83}
     84
     85struct crypto_aead *
     86aead_key_setup_encrypt(const char *alg, const u8 key[],
     87		       size_t key_len, size_t mic_len)
     88{
     89	struct crypto_aead *tfm;
     90	int err;
     91
     92	tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
     93	if (IS_ERR(tfm))
     94		return tfm;
     95
     96	err = crypto_aead_setkey(tfm, key, key_len);
     97	if (err)
     98		goto free_aead;
     99	err = crypto_aead_setauthsize(tfm, mic_len);
    100	if (err)
    101		goto free_aead;
    102
    103	return tfm;
    104
    105free_aead:
    106	crypto_free_aead(tfm);
    107	return ERR_PTR(err);
    108}
    109
    110void aead_key_free(struct crypto_aead *tfm)
    111{
    112	crypto_free_aead(tfm);
    113}