linux/drivers/crypto/atmel-sha.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Cryptographic API.
 *
 * Support for ATMEL SHA1/SHA256 HW acceleration.
 *
 * Copyright (c) 2012 Eukréa Electromatique - ATMEL
 * Author: Nicolas Royer <[email protected]>
 *
 * Some ideas are from omap-sham.c drivers.
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/hw_random.h>
#include <linux/platform_device.h>

#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/mod_devicetable.h>
#include <linux/delay.h>
#include <linux/crypto.h>
#include <crypto/scatterwalk.h>
#include <crypto/algapi.h>
#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#include "atmel-sha-regs.h"
#include "atmel-authenc.h"

#define ATMEL_SHA_PRIORITY

/* SHA flags */
#define SHA_FLAGS_BUSY
#define SHA_FLAGS_FINAL
#define SHA_FLAGS_DMA_ACTIVE
#define SHA_FLAGS_OUTPUT_READY
#define SHA_FLAGS_INIT
#define SHA_FLAGS_CPU
#define SHA_FLAGS_DMA_READY
#define SHA_FLAGS_DUMP_REG

/* bits[11:8] are reserved. */

#define SHA_FLAGS_FINUP
#define SHA_FLAGS_SG
#define SHA_FLAGS_ERROR
#define SHA_FLAGS_PAD
#define SHA_FLAGS_RESTORE
#define SHA_FLAGS_IDATAR0
#define SHA_FLAGS_WAIT_DATARDY

#define SHA_OP_INIT
#define SHA_OP_UPDATE
#define SHA_OP_FINAL
#define SHA_OP_DIGEST

#define SHA_BUFFER_LEN

#define ATMEL_SHA_DMA_THRESHOLD

struct atmel_sha_caps {};

struct atmel_sha_dev;

/*
 * .statesize = sizeof(struct atmel_sha_reqctx) must be <= PAGE_SIZE / 8 as
 * tested by the ahash_prepare_alg() function.
 */
struct atmel_sha_reqctx {};

atmel_sha_fn_t;

struct atmel_sha_ctx {};

#define ATMEL_SHA_QUEUE_LENGTH

struct atmel_sha_dma {};

struct atmel_sha_dev {};

struct atmel_sha_drv {};

static struct atmel_sha_drv atmel_sha =;

#ifdef VERBOSE_DEBUG
static const char *atmel_sha_reg_name(u32 offset, char *tmp, size_t sz, bool wr)
{
	switch (offset) {
	case SHA_CR:
		return "CR";

	case SHA_MR:
		return "MR";

	case SHA_IER:
		return "IER";

	case SHA_IDR:
		return "IDR";

	case SHA_IMR:
		return "IMR";

	case SHA_ISR:
		return "ISR";

	case SHA_MSR:
		return "MSR";

	case SHA_BCR:
		return "BCR";

	case SHA_REG_DIN(0):
	case SHA_REG_DIN(1):
	case SHA_REG_DIN(2):
	case SHA_REG_DIN(3):
	case SHA_REG_DIN(4):
	case SHA_REG_DIN(5):
	case SHA_REG_DIN(6):
	case SHA_REG_DIN(7):
	case SHA_REG_DIN(8):
	case SHA_REG_DIN(9):
	case SHA_REG_DIN(10):
	case SHA_REG_DIN(11):
	case SHA_REG_DIN(12):
	case SHA_REG_DIN(13):
	case SHA_REG_DIN(14):
	case SHA_REG_DIN(15):
		snprintf(tmp, sz, "IDATAR[%u]", (offset - SHA_REG_DIN(0)) >> 2);
		break;

	case SHA_REG_DIGEST(0):
	case SHA_REG_DIGEST(1):
	case SHA_REG_DIGEST(2):
	case SHA_REG_DIGEST(3):
	case SHA_REG_DIGEST(4):
	case SHA_REG_DIGEST(5):
	case SHA_REG_DIGEST(6):
	case SHA_REG_DIGEST(7):
	case SHA_REG_DIGEST(8):
	case SHA_REG_DIGEST(9):
	case SHA_REG_DIGEST(10):
	case SHA_REG_DIGEST(11):
	case SHA_REG_DIGEST(12):
	case SHA_REG_DIGEST(13):
	case SHA_REG_DIGEST(14):
	case SHA_REG_DIGEST(15):
		if (wr)
			snprintf(tmp, sz, "IDATAR[%u]",
				 16u + ((offset - SHA_REG_DIGEST(0)) >> 2));
		else
			snprintf(tmp, sz, "ODATAR[%u]",
				 (offset - SHA_REG_DIGEST(0)) >> 2);
		break;

	case SHA_HW_VERSION:
		return "HWVER";

	default:
		snprintf(tmp, sz, "0x%02x", offset);
		break;
	}

	return tmp;
}

#endif /* VERBOSE_DEBUG */

static inline u32 atmel_sha_read(struct atmel_sha_dev *dd, u32 offset)
{}

static inline void atmel_sha_write(struct atmel_sha_dev *dd,
					u32 offset, u32 value)
{}

static inline int atmel_sha_complete(struct atmel_sha_dev *dd, int err)
{}

static size_t atmel_sha_append_sg(struct atmel_sha_reqctx *ctx)
{}

/*
 * The purpose of this padding is to ensure that the padded message is a
 * multiple of 512 bits (SHA1/SHA224/SHA256) or 1024 bits (SHA384/SHA512).
 * The bit "1" is appended at the end of the message followed by
 * "padlen-1" zero bits. Then a 64 bits block (SHA1/SHA224/SHA256) or
 * 128 bits block (SHA384/SHA512) equals to the message length in bits
 * is appended.
 *
 * For SHA1/SHA224/SHA256, padlen is calculated as followed:
 *  - if message length < 56 bytes then padlen = 56 - message length
 *  - else padlen = 64 + 56 - message length
 *
 * For SHA384/SHA512, padlen is calculated as followed:
 *  - if message length < 112 bytes then padlen = 112 - message length
 *  - else padlen = 128 + 112 - message length
 */
static void atmel_sha_fill_padding(struct atmel_sha_reqctx *ctx, int length)
{}

static struct atmel_sha_dev *atmel_sha_find_dev(struct atmel_sha_ctx *tctx)
{}

static int atmel_sha_init(struct ahash_request *req)
{}

static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma)
{}

static inline int atmel_sha_wait_for_data_ready(struct atmel_sha_dev *dd,
						atmel_sha_fn_t resume)
{}

static int atmel_sha_xmit_cpu(struct atmel_sha_dev *dd, const u8 *buf,
			      size_t length, int final)
{}

static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{}

static void atmel_sha_dma_callback(void *data)
{}

static int atmel_sha_xmit_dma(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{}

static int atmel_sha_xmit_start(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{}

static int atmel_sha_update_cpu(struct atmel_sha_dev *dd)
{}

static int atmel_sha_xmit_dma_map(struct atmel_sha_dev *dd,
					struct atmel_sha_reqctx *ctx,
					size_t length, int final)
{}

static int atmel_sha_update_dma_slow(struct atmel_sha_dev *dd)
{}

static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd)
{}

static void atmel_sha_update_dma_stop(struct atmel_sha_dev *dd)
{}

static int atmel_sha_update_req(struct atmel_sha_dev *dd)
{}

static int atmel_sha_final_req(struct atmel_sha_dev *dd)
{}

static void atmel_sha_copy_hash(struct ahash_request *req)
{}

static void atmel_sha_copy_ready_hash(struct ahash_request *req)
{}

static int atmel_sha_finish(struct ahash_request *req)
{}

static void atmel_sha_finish_req(struct ahash_request *req, int err)
{}

static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
{}

static inline unsigned int atmel_sha_get_version(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
{}

static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
				  struct ahash_request *req)
{}

static int atmel_sha_done(struct atmel_sha_dev *dd);

static int atmel_sha_start(struct atmel_sha_dev *dd)
{}

static int atmel_sha_enqueue(struct ahash_request *req, unsigned int op)
{}

static int atmel_sha_update(struct ahash_request *req)
{}

static int atmel_sha_final(struct ahash_request *req)
{}

static int atmel_sha_finup(struct ahash_request *req)
{}

static int atmel_sha_digest(struct ahash_request *req)
{}


static int atmel_sha_export(struct ahash_request *req, void *out)
{}

static int atmel_sha_import(struct ahash_request *req, const void *in)
{}

static int atmel_sha_cra_init(struct crypto_tfm *tfm)
{}

static void atmel_sha_alg_init(struct ahash_alg *alg)
{}

static struct ahash_alg sha_1_256_algs[] =;

static struct ahash_alg sha_224_alg =;

static struct ahash_alg sha_384_512_algs[] =;

static void atmel_sha_queue_task(unsigned long data)
{}

static int atmel_sha_done(struct atmel_sha_dev *dd)
{}

static void atmel_sha_done_task(unsigned long data)
{}

static irqreturn_t atmel_sha_irq(int irq, void *dev_id)
{}


/* DMA transfer functions */

static bool atmel_sha_dma_check_aligned(struct atmel_sha_dev *dd,
					struct scatterlist *sg,
					size_t len)
{}

static void atmel_sha_dma_callback2(void *data)
{}

static int atmel_sha_dma_start(struct atmel_sha_dev *dd,
			       struct scatterlist *src,
			       size_t len,
			       atmel_sha_fn_t resume)
{}


/* CPU transfer functions */

static int atmel_sha_cpu_transfer(struct atmel_sha_dev *dd)
{}

static int atmel_sha_cpu_start(struct atmel_sha_dev *dd,
			       struct scatterlist *sg,
			       unsigned int len,
			       bool idatar0_only,
			       bool wait_data_ready,
			       atmel_sha_fn_t resume)
{}

static int atmel_sha_cpu_hash(struct atmel_sha_dev *dd,
			      const void *data, unsigned int datalen,
			      bool auto_padding,
			      atmel_sha_fn_t resume)
{}


/* hmac functions */

struct atmel_sha_hmac_key {};

static inline void atmel_sha_hmac_key_init(struct atmel_sha_hmac_key *hkey)
{}

static inline void atmel_sha_hmac_key_release(struct atmel_sha_hmac_key *hkey)
{}

static inline int atmel_sha_hmac_key_set(struct atmel_sha_hmac_key *hkey,
					 const u8 *key,
					 unsigned int keylen)
{}

static inline bool atmel_sha_hmac_key_get(const struct atmel_sha_hmac_key *hkey,
					  const u8 **key,
					  unsigned int *keylen)
{}


struct atmel_sha_hmac_ctx {};

static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
				atmel_sha_fn_t resume);
static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
				      const u8 *key, unsigned int keylen);
static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd);

static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd);

static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
				atmel_sha_fn_t resume)
{}

static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
				      const u8 *key, unsigned int keylen)
{}

static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_start(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
				 unsigned int keylen)
{}

static int atmel_sha_hmac_init(struct ahash_request *req)
{}

static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_final(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_digest(struct ahash_request *req)
{}

static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd)
{}

static int atmel_sha_hmac_cra_init(struct crypto_tfm *tfm)
{}

static void atmel_sha_hmac_cra_exit(struct crypto_tfm *tfm)
{}

static void atmel_sha_hmac_alg_init(struct ahash_alg *alg)
{}

static struct ahash_alg sha_hmac_algs[] =;

#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
/* authenc functions */

static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd);


struct atmel_sha_authenc_ctx {};

struct atmel_sha_authenc_reqctx {};

static void atmel_sha_authenc_complete(void *data, int err)
{}

static int atmel_sha_authenc_start(struct atmel_sha_dev *dd)
{}

bool atmel_sha_authenc_is_ready(void)
{}
EXPORT_SYMBOL_GPL();

unsigned int atmel_sha_authenc_get_reqsize(void)
{}
EXPORT_SYMBOL_GPL();

struct atmel_sha_authenc_ctx *atmel_sha_authenc_spawn(unsigned long mode)
{}
EXPORT_SYMBOL_GPL();

void atmel_sha_authenc_free(struct atmel_sha_authenc_ctx *auth)
{}
EXPORT_SYMBOL_GPL();

int atmel_sha_authenc_setkey(struct atmel_sha_authenc_ctx *auth,
			     const u8 *key, unsigned int keylen, u32 flags)
{}
EXPORT_SYMBOL_GPL();

int atmel_sha_authenc_schedule(struct ahash_request *req,
			       struct atmel_sha_authenc_ctx *auth,
			       atmel_aes_authenc_fn_t cb,
			       struct atmel_aes_dev *aes_dev)
{}
EXPORT_SYMBOL_GPL();

int atmel_sha_authenc_init(struct ahash_request *req,
			   struct scatterlist *assoc, unsigned int assoclen,
			   unsigned int textlen,
			   atmel_aes_authenc_fn_t cb,
			   struct atmel_aes_dev *aes_dev)
{}
EXPORT_SYMBOL_GPL();

static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd)
{}

static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd)
{}

int atmel_sha_authenc_final(struct ahash_request *req,
			    u32 *digest, unsigned int digestlen,
			    atmel_aes_authenc_fn_t cb,
			    struct atmel_aes_dev *aes_dev)
{}
EXPORT_SYMBOL_GPL();

static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd)
{}

void atmel_sha_authenc_abort(struct ahash_request *req)
{}
EXPORT_SYMBOL_GPL();

#endif /* CONFIG_CRYPTO_DEV_ATMEL_AUTHENC */


static void atmel_sha_unregister_algs(struct atmel_sha_dev *dd)
{}

static int atmel_sha_register_algs(struct atmel_sha_dev *dd)
{}

static int atmel_sha_dma_init(struct atmel_sha_dev *dd)
{}

static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd)
{}

static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
{}

static const struct of_device_id atmel_sha_dt_ids[] =;

MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids);

static int atmel_sha_probe(struct platform_device *pdev)
{}

static void atmel_sha_remove(struct platform_device *pdev)
{}

static struct platform_driver atmel_sha_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_AUTHOR();