^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Cryptographic API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Support for Samsung S5PV210 and Exynos HW acceleration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Copyright (C) 2011 NetUP Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) // Hash part based on omap-sham.c driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/crypto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <crypto/ctr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <crypto/aes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <crypto/algapi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <crypto/scatterwalk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <crypto/md5.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <crypto/sha.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <crypto/internal/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define _SBF(s, v) ((v) << (s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Feed control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SSS_REG_FCINTSTAT 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SSS_FCINTSTAT_HPARTINT BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SSS_FCINTSTAT_HDONEINT BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SSS_FCINTSTAT_BRDMAINT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SSS_FCINTSTAT_BTDMAINT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SSS_FCINTSTAT_HRDMAINT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SSS_FCINTSTAT_PKDMAINT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SSS_REG_FCINTENSET 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SSS_FCINTENSET_HPARTINTENSET BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SSS_FCINTENSET_HDONEINTENSET BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SSS_FCINTENSET_BRDMAINTENSET BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SSS_FCINTENSET_BTDMAINTENSET BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SSS_FCINTENSET_HRDMAINTENSET BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SSS_FCINTENSET_PKDMAINTENSET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SSS_REG_FCINTENCLR 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SSS_FCINTENCLR_HPARTINTENCLR BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SSS_FCINTENCLR_HDONEINTENCLR BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SSS_FCINTENCLR_BRDMAINTENCLR BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SSS_FCINTENCLR_BTDMAINTENCLR BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SSS_FCINTENCLR_HRDMAINTENCLR BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SSS_FCINTENCLR_PKDMAINTENCLR BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SSS_REG_FCINTPEND 0x000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SSS_FCINTPEND_HPARTINTP BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SSS_FCINTPEND_HDONEINTP BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SSS_FCINTPEND_BRDMAINTP BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SSS_FCINTPEND_BTDMAINTP BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SSS_FCINTPEND_HRDMAINTP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SSS_FCINTPEND_PKDMAINTP BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SSS_REG_FCFIFOSTAT 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SSS_FCFIFOSTAT_BRFIFOFUL BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SSS_FCFIFOSTAT_BRFIFOEMP BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SSS_FCFIFOSTAT_BTFIFOFUL BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SSS_FCFIFOSTAT_BTFIFOEMP BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SSS_FCFIFOSTAT_HRFIFOFUL BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SSS_FCFIFOSTAT_HRFIFOEMP BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SSS_FCFIFOSTAT_PKFIFOFUL BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SSS_FCFIFOSTAT_PKFIFOEMP BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SSS_REG_FCFIFOCTRL 0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SSS_FCFIFOCTRL_DESSEL BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SSS_HASHIN_INDEPENDENT _SBF(0, 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SSS_HASHIN_CIPHER_INPUT _SBF(0, 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SSS_HASHIN_CIPHER_OUTPUT _SBF(0, 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SSS_HASHIN_MASK _SBF(0, 0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SSS_REG_FCBRDMAS 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SSS_REG_FCBRDMAL 0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SSS_REG_FCBRDMAC 0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define SSS_FCBRDMAC_BYTESWAP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define SSS_FCBRDMAC_FLUSH BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SSS_REG_FCBTDMAS 0x0030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SSS_REG_FCBTDMAL 0x0034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SSS_REG_FCBTDMAC 0x0038
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SSS_FCBTDMAC_BYTESWAP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SSS_FCBTDMAC_FLUSH BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SSS_REG_FCHRDMAS 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define SSS_REG_FCHRDMAL 0x0044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SSS_REG_FCHRDMAC 0x0048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SSS_FCHRDMAC_BYTESWAP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SSS_FCHRDMAC_FLUSH BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SSS_REG_FCPKDMAS 0x0050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SSS_REG_FCPKDMAL 0x0054
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define SSS_REG_FCPKDMAC 0x0058
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SSS_FCPKDMAC_BYTESWAP BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define SSS_FCPKDMAC_DESCEND BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define SSS_FCPKDMAC_TRANSMIT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define SSS_FCPKDMAC_FLUSH BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define SSS_REG_FCPKDMAO 0x005C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* AES registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define SSS_REG_AES_CONTROL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define SSS_AES_BYTESWAP_DI BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define SSS_AES_BYTESWAP_DO BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define SSS_AES_BYTESWAP_IV BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define SSS_AES_BYTESWAP_CNT BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define SSS_AES_BYTESWAP_KEY BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define SSS_AES_KEY_CHANGE_MODE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define SSS_AES_KEY_SIZE_128 _SBF(4, 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define SSS_AES_KEY_SIZE_192 _SBF(4, 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define SSS_AES_KEY_SIZE_256 _SBF(4, 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define SSS_AES_FIFO_MODE BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define SSS_AES_CHAIN_MODE_ECB _SBF(1, 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define SSS_AES_CHAIN_MODE_CBC _SBF(1, 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define SSS_AES_CHAIN_MODE_CTR _SBF(1, 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define SSS_AES_MODE_DECRYPT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define SSS_REG_AES_STATUS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define SSS_AES_BUSY BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define SSS_AES_INPUT_READY BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SSS_AES_OUTPUT_READY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SSS_REG_AES_IN_DATA(s) (0x10 + (s << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SSS_REG_AES_OUT_DATA(s) (0x20 + (s << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SSS_REG_AES_IV_DATA(s) (0x30 + (s << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define SSS_REG_AES_CNT_DATA(s) (0x40 + (s << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define SSS_REG_AES_KEY_DATA(s) (0x80 + (s << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SSS_REG(dev, reg) ((dev)->ioaddr + (SSS_REG_##reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SSS_READ(dev, reg) __raw_readl(SSS_REG(dev, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define SSS_WRITE(dev, reg, val) __raw_writel((val), SSS_REG(dev, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define SSS_AES_REG(dev, reg) ((dev)->aes_ioaddr + SSS_REG_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define SSS_AES_WRITE(dev, reg, val) __raw_writel((val), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) SSS_AES_REG(dev, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* HW engine modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define FLAGS_AES_DECRYPT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define FLAGS_AES_MODE_MASK _SBF(1, 0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define FLAGS_AES_CBC _SBF(1, 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define FLAGS_AES_CTR _SBF(1, 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define AES_KEY_LEN 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define CRYPTO_QUEUE_LEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* HASH registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define SSS_REG_HASH_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define SSS_HASH_USER_IV_EN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define SSS_HASH_INIT_BIT BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define SSS_HASH_ENGINE_SHA1 _SBF(1, 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define SSS_HASH_ENGINE_MD5 _SBF(1, 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define SSS_HASH_ENGINE_SHA256 _SBF(1, 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define SSS_HASH_ENGINE_MASK _SBF(1, 0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define SSS_REG_HASH_CTRL_PAUSE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define SSS_HASH_PAUSE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define SSS_REG_HASH_CTRL_FIFO 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define SSS_HASH_FIFO_MODE_DMA BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define SSS_HASH_FIFO_MODE_CPU 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define SSS_REG_HASH_CTRL_SWAP 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define SSS_HASH_BYTESWAP_DI BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define SSS_HASH_BYTESWAP_DO BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define SSS_HASH_BYTESWAP_IV BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define SSS_HASH_BYTESWAP_KEY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define SSS_REG_HASH_STATUS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define SSS_HASH_STATUS_MSG_DONE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define SSS_HASH_STATUS_PARTIAL_DONE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define SSS_HASH_STATUS_BUFFER_READY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define SSS_REG_HASH_MSG_SIZE_LOW 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define SSS_REG_HASH_MSG_SIZE_HIGH 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define SSS_REG_HASH_PRE_MSG_SIZE_LOW 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define SSS_REG_HASH_PRE_MSG_SIZE_HIGH 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define SSS_REG_HASH_IV(s) (0xB0 + ((s) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define SSS_REG_HASH_OUT(s) (0x100 + ((s) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define HASH_BLOCK_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define HASH_REG_SIZEOF 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define HASH_MD5_MAX_REG (MD5_DIGEST_SIZE / HASH_REG_SIZEOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define HASH_SHA1_MAX_REG (SHA1_DIGEST_SIZE / HASH_REG_SIZEOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define HASH_SHA256_MAX_REG (SHA256_DIGEST_SIZE / HASH_REG_SIZEOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * HASH bit numbers, used by device, setting in dev->hash_flags with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * functions set_bit(), clear_bit() or tested with test_bit() or BIT(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * to keep HASH state BUSY or FREE, or to signal state from irq_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * to hash_tasklet. SGS keep track of allocated memory for scatterlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define HASH_FLAGS_BUSY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define HASH_FLAGS_FINAL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define HASH_FLAGS_DMA_ACTIVE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define HASH_FLAGS_OUTPUT_READY 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define HASH_FLAGS_DMA_READY 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define HASH_FLAGS_SGS_COPIED 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define HASH_FLAGS_SGS_ALLOCED 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* HASH HW constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define BUFLEN HASH_BLOCK_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define SSS_HASH_DMA_LEN_ALIGN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define SSS_HASH_DMA_ALIGN_MASK (SSS_HASH_DMA_LEN_ALIGN - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define SSS_HASH_QUEUE_LENGTH 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * struct samsung_aes_variant - platform specific SSS driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @aes_offset: AES register offset from SSS module's base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @hash_offset: HASH register offset from SSS module's base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @clk_names: names of clocks needed to run SSS IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Specifies platform specific configuration of SSS module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Note: A structure for driver specific platform data is used for future
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * expansion of its usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct samsung_aes_variant {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int aes_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned int hash_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) const char *clk_names[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct s5p_aes_reqctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct s5p_aes_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct s5p_aes_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u8 aes_key[AES_MAX_KEY_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u8 nonce[CTR_RFC3686_NONCE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * struct s5p_aes_dev - Crypto device state container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * @dev: Associated device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @clk: Clock for accessing hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * @pclk: APB bus clock necessary to access the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @ioaddr: Mapped IO memory region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * @aes_ioaddr: Per-varian offset for AES block IO memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * @irq_fc: Feed control interrupt line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * @req: Crypto request currently handled by the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * @ctx: Configuration for currently handled crypto request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @sg_src: Scatter list with source data for currently handled block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * in device. This is DMA-mapped into device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @sg_dst: Scatter list with destination data for currently handled block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * in device. This is DMA-mapped into device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * @sg_src_cpy: In case of unaligned access, copied scatter list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * with source data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @sg_dst_cpy: In case of unaligned access, copied scatter list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * with destination data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @tasklet: New request scheduling jib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @queue: Crypto queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @busy: Indicates whether the device is currently handling some request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * thus it uses some of the fields from this state, like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * req, ctx, sg_src/dst (and copies). This essentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * protects against concurrent access to these fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * @lock: Lock for protecting both access to device hardware registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * and fields related to current request (including the busy field).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * @res: Resources for hash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * @io_hash_base: Per-variant offset for HASH block IO memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * @hash_lock: Lock for protecting hash_req, hash_queue and hash_flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * @hash_flags: Flags for current HASH op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * @hash_queue: Async hash queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * @hash_tasklet: New HASH request scheduling job.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @xmit_buf: Buffer for current HASH request transfer into SSS block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @hash_req: Current request sending to SSS HASH block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * @hash_sg_iter: Scatterlist transferred through DMA into SSS HASH block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @hash_sg_cnt: Counter for hash_sg_iter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * @use_hash: true if HASH algs enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct s5p_aes_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct clk *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void __iomem *ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void __iomem *aes_ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int irq_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct skcipher_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct s5p_aes_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct scatterlist *sg_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct scatterlist *sg_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct scatterlist *sg_src_cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct scatterlist *sg_dst_cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct tasklet_struct tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct crypto_queue queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) bool busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) void __iomem *io_hash_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) spinlock_t hash_lock; /* protect hash_ vars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long hash_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct crypto_queue hash_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct tasklet_struct hash_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u8 xmit_buf[BUFLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct ahash_request *hash_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct scatterlist *hash_sg_iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned int hash_sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) bool use_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * struct s5p_hash_reqctx - HASH request context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * @dd: Associated device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * @op_update: Current request operation (OP_UPDATE or OP_FINAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * @digcnt: Number of bytes processed by HW (without buffer[] ones)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * @digest: Digest message or IV for partial result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * @nregs: Number of HW registers for digest or IV read/write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * @engine: Bits for selecting type of HASH in SSS block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * @sg: sg for DMA transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @sg_len: Length of sg for DMA transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * @sgl: sg for joining buffer and req->src scatterlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * @skip: Skip offset in req->src for current op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * @total: Total number of bytes for current request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * @finup: Keep state for finup or final.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * @error: Keep track of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @bufcnt: Number of bytes holded in buffer[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * @buffer: For byte(s) from end of req->src in UPDATE op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct s5p_hash_reqctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct s5p_aes_dev *dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bool op_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u64 digcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) u8 digest[SHA256_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) unsigned int nregs; /* digest_size / sizeof(reg) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) u32 engine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned int sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct scatterlist sgl[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned int skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned int total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bool finup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) bool error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u32 bufcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u8 buffer[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * struct s5p_hash_ctx - HASH transformation context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * @dd: Associated device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @flags: Bits for algorithm HASH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * @fallback: Software transformation for zero message or size < BUFLEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct s5p_hash_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct s5p_aes_dev *dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct crypto_shash *fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static const struct samsung_aes_variant s5p_aes_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .aes_offset = 0x4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .hash_offset = 0x6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .clk_names = { "secss", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static const struct samsung_aes_variant exynos_aes_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .aes_offset = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .hash_offset = 0x400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .clk_names = { "secss", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static const struct samsung_aes_variant exynos5433_slim_aes_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .aes_offset = 0x400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .hash_offset = 0x800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .clk_names = { "pclk", "aclk", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static const struct of_device_id s5p_sss_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .compatible = "samsung,s5pv210-secss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .data = &s5p_aes_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .compatible = "samsung,exynos4210-secss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .data = &exynos_aes_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .compatible = "samsung,exynos5433-slim-sss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .data = &exynos5433_slim_aes_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) MODULE_DEVICE_TABLE(of, s5p_sss_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static inline const struct samsung_aes_variant *find_s5p_sss_version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) (const struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (IS_ENABLED(CONFIG_OF) && (pdev->dev.of_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) match = of_match_node(s5p_sss_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return (const struct samsung_aes_variant *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return (const struct samsung_aes_variant *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) platform_get_device_id(pdev)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static struct s5p_aes_dev *s5p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void s5p_set_dma_indata(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) const struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) SSS_WRITE(dev, FCBRDMAS, sg_dma_address(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) SSS_WRITE(dev, FCBRDMAL, sg_dma_len(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static void s5p_set_dma_outdata(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) const struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) SSS_WRITE(dev, FCBTDMAS, sg_dma_address(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) SSS_WRITE(dev, FCBTDMAL, sg_dma_len(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static void s5p_free_sg_cpy(struct s5p_aes_dev *dev, struct scatterlist **sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!*sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) len = ALIGN(dev->req->cryptlen, AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) free_pages((unsigned long)sg_virt(*sg), get_order(len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) kfree(*sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *sg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static void s5p_sg_copy_buf(void *buf, struct scatterlist *sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) unsigned int nbytes, int out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct scatter_walk walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (!nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) scatterwalk_start(&walk, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) scatterwalk_copychunks(buf, &walk, nbytes, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) scatterwalk_done(&walk, out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static void s5p_sg_done(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct skcipher_request *req = dev->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct s5p_aes_reqctx *reqctx = skcipher_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (dev->sg_dst_cpy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dev_dbg(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) "Copying %d bytes of output data back to original place\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dev->req->cryptlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) s5p_sg_copy_buf(sg_virt(dev->sg_dst_cpy), dev->req->dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dev->req->cryptlen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) s5p_free_sg_cpy(dev, &dev->sg_src_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) s5p_free_sg_cpy(dev, &dev->sg_dst_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (reqctx->mode & FLAGS_AES_CBC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) memcpy_fromio(req->iv, dev->aes_ioaddr + SSS_REG_AES_IV_DATA(0), AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) else if (reqctx->mode & FLAGS_AES_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) memcpy_fromio(req->iv, dev->aes_ioaddr + SSS_REG_AES_CNT_DATA(0), AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Calls the completion. Cannot be called with dev->lock hold. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static void s5p_aes_complete(struct skcipher_request *req, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) req->base.complete(&req->base, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void s5p_unset_outdata(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dma_unmap_sg(dev->dev, dev->sg_dst, 1, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static void s5p_unset_indata(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dma_unmap_sg(dev->dev, dev->sg_src, 1, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int s5p_make_sg_cpy(struct s5p_aes_dev *dev, struct scatterlist *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct scatterlist **dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) void *pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) *dst = kmalloc(sizeof(**dst), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!*dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) len = ALIGN(dev->req->cryptlen, AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) pages = (void *)__get_free_pages(GFP_ATOMIC, get_order(len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (!pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) kfree(*dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) s5p_sg_copy_buf(pages, src, dev->req->cryptlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) sg_init_table(*dst, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) sg_set_buf(*dst, pages, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static int s5p_set_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!sg->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!dma_map_sg(dev->dev, sg, 1, DMA_FROM_DEVICE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dev->sg_dst = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static int s5p_set_indata(struct s5p_aes_dev *dev, struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (!sg->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!dma_map_sg(dev->dev, sg, 1, DMA_TO_DEVICE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dev->sg_src = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * Returns -ERRNO on error (mapping of new data failed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * On success returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * - 0 if there is no more data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * - 1 if new transmitting (output) data is ready and its address+length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * have to be written to device (by calling s5p_set_dma_outdata()).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int s5p_aes_tx(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) s5p_unset_outdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!sg_is_last(dev->sg_dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ret = s5p_set_outdata(dev, sg_next(dev->sg_dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * Returns -ERRNO on error (mapping of new data failed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * On success returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * - 0 if there is no more data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * - 1 if new receiving (input) data is ready and its address+length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * have to be written to device (by calling s5p_set_dma_indata()).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int s5p_aes_rx(struct s5p_aes_dev *dev/*, bool *set_dma*/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) s5p_unset_indata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!sg_is_last(dev->sg_src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ret = s5p_set_indata(dev, sg_next(dev->sg_src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static inline u32 s5p_hash_read(struct s5p_aes_dev *dd, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return __raw_readl(dd->io_hash_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static inline void s5p_hash_write(struct s5p_aes_dev *dd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u32 offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) __raw_writel(value, dd->io_hash_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * s5p_set_dma_hashdata() - start DMA with sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * @dev: device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * @sg: scatterlist ready to DMA transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static void s5p_set_dma_hashdata(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) const struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dev->hash_sg_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) SSS_WRITE(dev, FCHRDMAS, sg_dma_address(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) SSS_WRITE(dev, FCHRDMAL, sg_dma_len(sg)); /* DMA starts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * s5p_hash_rx() - get next hash_sg_iter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * @dev: device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * 2 if there is no more data and it is UPDATE op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * 1 if new receiving (input) data is ready and can be written to device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * 0 if there is no more data and it is FINAL op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int s5p_hash_rx(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (dev->hash_sg_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dev->hash_sg_iter = sg_next(dev->hash_sg_iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) set_bit(HASH_FLAGS_DMA_READY, &dev->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (test_bit(HASH_FLAGS_FINAL, &dev->hash_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct platform_device *pdev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct s5p_aes_dev *dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct skcipher_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int err_dma_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int err_dma_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int err_dma_hx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) bool tx_end = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bool hx_end = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) u32 status, st_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) spin_lock_irqsave(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * Handle rx or tx interrupt. If there is still data (scatterlist did not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * reach end), then map next scatterlist entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * In case of such mapping error, s5p_aes_complete() should be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * If there is no more data in tx scatter list, call s5p_aes_complete()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * and schedule new tasklet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * Handle hx interrupt. If there is still data map next entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) status = SSS_READ(dev, FCINTSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (status & SSS_FCINTSTAT_BRDMAINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) err_dma_rx = s5p_aes_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (status & SSS_FCINTSTAT_BTDMAINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (sg_is_last(dev->sg_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) tx_end = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) err_dma_tx = s5p_aes_tx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (status & SSS_FCINTSTAT_HRDMAINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) err_dma_hx = s5p_hash_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) st_bits = status & (SSS_FCINTSTAT_BRDMAINT | SSS_FCINTSTAT_BTDMAINT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) SSS_FCINTSTAT_HRDMAINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* clear DMA bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) SSS_WRITE(dev, FCINTPEND, st_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* clear HASH irq bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (status & (SSS_FCINTSTAT_HDONEINT | SSS_FCINTSTAT_HPARTINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* cannot have both HPART and HDONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (status & SSS_FCINTSTAT_HPARTINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) st_bits = SSS_HASH_STATUS_PARTIAL_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (status & SSS_FCINTSTAT_HDONEINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) st_bits = SSS_HASH_STATUS_MSG_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) set_bit(HASH_FLAGS_OUTPUT_READY, &dev->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) s5p_hash_write(dev, SSS_REG_HASH_STATUS, st_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hx_end = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* when DONE or PART, do not handle HASH DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) err_dma_hx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (err_dma_rx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) err = err_dma_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (err_dma_tx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) err = err_dma_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (tx_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) s5p_sg_done(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (err_dma_hx == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) s5p_set_dma_hashdata(dev, dev->hash_sg_iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) s5p_aes_complete(dev->req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Device is still busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) tasklet_schedule(&dev->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * Writing length of DMA block (either receiving or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * transmitting) will start the operation immediately, so this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * should be done at the end (even after clearing pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * interrupts to not miss the interrupt).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (err_dma_tx == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) s5p_set_dma_outdata(dev, dev->sg_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (err_dma_rx == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) s5p_set_dma_indata(dev, dev->sg_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (err_dma_hx == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) s5p_set_dma_hashdata(dev, dev->hash_sg_iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) goto hash_irq_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) s5p_sg_done(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) dev->busy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) req = dev->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (err_dma_hx == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) s5p_set_dma_hashdata(dev, dev->hash_sg_iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) s5p_aes_complete(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) hash_irq_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Note about else if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * when hash_sg_iter reaches end and its UPDATE op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * issue SSS_HASH_PAUSE and wait for HPART irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (hx_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) tasklet_schedule(&dev->hash_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) else if (err_dma_hx == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) s5p_hash_write(dev, SSS_REG_HASH_CTRL_PAUSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) SSS_HASH_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * s5p_hash_read_msg() - read message or IV from HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static void s5p_hash_read_msg(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct s5p_aes_dev *dd = ctx->dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) u32 *hash = (u32 *)ctx->digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) for (i = 0; i < ctx->nregs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) hash[i] = s5p_hash_read(dd, SSS_REG_HASH_OUT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * s5p_hash_write_ctx_iv() - write IV for next partial/finup op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * @dd: device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * @ctx: request context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static void s5p_hash_write_ctx_iv(struct s5p_aes_dev *dd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) const struct s5p_hash_reqctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const u32 *hash = (const u32 *)ctx->digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) for (i = 0; i < ctx->nregs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) s5p_hash_write(dd, SSS_REG_HASH_IV(i), hash[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * s5p_hash_write_iv() - write IV for next partial/finup op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static void s5p_hash_write_iv(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) s5p_hash_write_ctx_iv(ctx->dd, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * s5p_hash_copy_result() - copy digest into req->result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static void s5p_hash_copy_result(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) const struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!req->result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) memcpy(req->result, ctx->digest, ctx->nregs * HASH_REG_SIZEOF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * s5p_hash_dma_flush() - flush HASH DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static void s5p_hash_dma_flush(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) SSS_WRITE(dev, FCHRDMAC, SSS_FCHRDMAC_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * s5p_hash_dma_enable() - enable DMA mode for HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * enable DMA mode for HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static void s5p_hash_dma_enable(struct s5p_aes_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) s5p_hash_write(dev, SSS_REG_HASH_CTRL_FIFO, SSS_HASH_FIFO_MODE_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * s5p_hash_irq_disable() - disable irq HASH signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @flags: bitfield with irq's to be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static void s5p_hash_irq_disable(struct s5p_aes_dev *dev, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) SSS_WRITE(dev, FCINTENCLR, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * s5p_hash_irq_enable() - enable irq signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * @flags: bitfield with irq's to be enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static void s5p_hash_irq_enable(struct s5p_aes_dev *dev, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) SSS_WRITE(dev, FCINTENSET, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * s5p_hash_set_flow() - set flow inside SecSS AES/DES with/without HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * @hashflow: HASH stream flow with/without crypto AES/DES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static void s5p_hash_set_flow(struct s5p_aes_dev *dev, u32 hashflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u32 flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) spin_lock_irqsave(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) flow = SSS_READ(dev, FCFIFOCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) flow &= ~SSS_HASHIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) flow |= hashflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) SSS_WRITE(dev, FCFIFOCTRL, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * s5p_ahash_dma_init() - enable DMA and set HASH flow inside SecSS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * @dev: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * @hashflow: HASH stream flow with/without AES/DES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * flush HASH DMA and enable DMA, set HASH stream flow inside SecSS HW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * enable HASH irq's HRDMA, HDONE, HPART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static void s5p_ahash_dma_init(struct s5p_aes_dev *dev, u32 hashflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) s5p_hash_irq_disable(dev, SSS_FCINTENCLR_HRDMAINTENCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) SSS_FCINTENCLR_HDONEINTENCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) SSS_FCINTENCLR_HPARTINTENCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) s5p_hash_dma_flush(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) s5p_hash_dma_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) s5p_hash_set_flow(dev, hashflow & SSS_HASHIN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) s5p_hash_irq_enable(dev, SSS_FCINTENSET_HRDMAINTENSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) SSS_FCINTENSET_HDONEINTENSET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) SSS_FCINTENSET_HPARTINTENSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * s5p_hash_write_ctrl() - prepare HASH block in SecSS for processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * @dd: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * @length: length for request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * @final: true if final op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * Prepare SSS HASH block for processing bytes in DMA mode. If it is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * after previous updates, fill up IV words. For final, calculate and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * lengths for HASH so SecSS can finalize hash. For partial, set SSS HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * length as 2^63 so it will be never reached and set to zero prelow and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * prehigh.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * This function does not start DMA transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static void s5p_hash_write_ctrl(struct s5p_aes_dev *dd, size_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) bool final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct s5p_hash_reqctx *ctx = ahash_request_ctx(dd->hash_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u32 prelow, prehigh, low, high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) u32 configflags, swapflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) u64 tmplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) configflags = ctx->engine | SSS_HASH_INIT_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (likely(ctx->digcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) s5p_hash_write_ctx_iv(dd, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) configflags |= SSS_HASH_USER_IV_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (final) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* number of bytes for last part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) low = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) high = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* total number of bits prev hashed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) tmplen = ctx->digcnt * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) prelow = (u32)tmplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) prehigh = (u32)(tmplen >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) prelow = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) prehigh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) low = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) high = BIT(31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) swapflags = SSS_HASH_BYTESWAP_DI | SSS_HASH_BYTESWAP_DO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) SSS_HASH_BYTESWAP_IV | SSS_HASH_BYTESWAP_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) s5p_hash_write(dd, SSS_REG_HASH_MSG_SIZE_LOW, low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) s5p_hash_write(dd, SSS_REG_HASH_MSG_SIZE_HIGH, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) s5p_hash_write(dd, SSS_REG_HASH_PRE_MSG_SIZE_LOW, prelow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) s5p_hash_write(dd, SSS_REG_HASH_PRE_MSG_SIZE_HIGH, prehigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) s5p_hash_write(dd, SSS_REG_HASH_CTRL_SWAP, swapflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) s5p_hash_write(dd, SSS_REG_HASH_CTRL, configflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * s5p_hash_xmit_dma() - start DMA hash processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * @dd: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * @length: length for request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * @final: true if final op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * Update digcnt here, as it is needed for finup/final op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) static int s5p_hash_xmit_dma(struct s5p_aes_dev *dd, size_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) bool final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) struct s5p_hash_reqctx *ctx = ahash_request_ctx(dd->hash_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) unsigned int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) cnt = dma_map_sg(dd->dev, ctx->sg, ctx->sg_len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) dev_err(dd->dev, "dma_map_sg error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) set_bit(HASH_FLAGS_DMA_ACTIVE, &dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dd->hash_sg_iter = ctx->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dd->hash_sg_cnt = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) s5p_hash_write_ctrl(dd, length, final);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ctx->digcnt += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ctx->total -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* catch last interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) set_bit(HASH_FLAGS_FINAL, &dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) s5p_set_dma_hashdata(dd, dd->hash_sg_iter); /* DMA starts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * s5p_hash_copy_sgs() - copy request's bytes into new buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * @ctx: request context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * @sg: source scatterlist request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * @new_len: number of bytes to process from sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * Allocate new buffer, copy data for HASH into it. If there was xmit_buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * filled, copy it first, then copy data from sg into it. Prepare one sgl[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * with allocated buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * Set bit in dd->hash_flag so we can free it after irq ends processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int s5p_hash_copy_sgs(struct s5p_hash_reqctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct scatterlist *sg, unsigned int new_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) unsigned int pages, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) len = new_len + ctx->bufcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pages = get_order(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) buf = (void *)__get_free_pages(GFP_ATOMIC, pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) dev_err(ctx->dd->dev, "alloc pages for unaligned case.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (ctx->bufcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) memcpy(buf, ctx->dd->xmit_buf, ctx->bufcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) scatterwalk_map_and_copy(buf + ctx->bufcnt, sg, ctx->skip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) new_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) sg_init_table(ctx->sgl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) sg_set_buf(ctx->sgl, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) ctx->sg = ctx->sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) ctx->sg_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ctx->bufcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ctx->skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) set_bit(HASH_FLAGS_SGS_COPIED, &ctx->dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * s5p_hash_copy_sg_lists() - copy sg list and make fixes in copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * @ctx: request context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * @sg: source scatterlist request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * @new_len: number of bytes to process from sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * Allocate new scatterlist table, copy data for HASH into it. If there was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * xmit_buf filled, prepare it first, then copy page, length and offset from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * source sg into it, adjusting begin and/or end for skip offset and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * hash_later value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * Resulting sg table will be assigned to ctx->sg. Set flag so we can free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * it after irq ends processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static int s5p_hash_copy_sg_lists(struct s5p_hash_reqctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct scatterlist *sg, unsigned int new_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) unsigned int skip = ctx->skip, n = sg_nents(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct scatterlist *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (ctx->bufcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) ctx->sg = kmalloc_array(n, sizeof(*sg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (!ctx->sg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sg_init_table(ctx->sg, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) tmp = ctx->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ctx->sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (ctx->bufcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) sg_set_buf(tmp, ctx->dd->xmit_buf, ctx->bufcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) tmp = sg_next(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) ctx->sg_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) while (sg && skip >= sg->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) skip -= sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) while (sg && new_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) len = sg->length - skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (new_len < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) len = new_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) new_len -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sg_set_page(tmp, sg_page(sg), len, sg->offset + skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (new_len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) sg_mark_end(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) tmp = sg_next(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ctx->sg_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) set_bit(HASH_FLAGS_SGS_ALLOCED, &ctx->dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * s5p_hash_prepare_sgs() - prepare sg for processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * @ctx: request context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * @sg: source scatterlist request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * @new_len: number of bytes to process from sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * @final: final flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * Check two conditions: (1) if buffers in sg have len aligned data, and (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * sg table have good aligned elements (list_ok). If one of this checks fails,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * then either (1) allocates new buffer for data with s5p_hash_copy_sgs, copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * data into this buffer and prepare request in sgl, or (2) allocates new sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * table and prepare sg elements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * For digest or finup all conditions can be good, and we may not need any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * fixes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static int s5p_hash_prepare_sgs(struct s5p_hash_reqctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct scatterlist *sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) unsigned int new_len, bool final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) unsigned int skip = ctx->skip, nbytes = new_len, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) bool aligned = true, list_ok = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct scatterlist *sg_tmp = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (!sg || !sg->length || !new_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (skip || !final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) list_ok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) while (nbytes > 0 && sg_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (skip >= sg_tmp->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) skip -= sg_tmp->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!sg_tmp->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) aligned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (!IS_ALIGNED(sg_tmp->length - skip, BUFLEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) aligned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (nbytes < sg_tmp->length - skip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) list_ok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) nbytes -= sg_tmp->length - skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) sg_tmp = sg_next(sg_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!aligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return s5p_hash_copy_sgs(ctx, sg, new_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) else if (!list_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return s5p_hash_copy_sg_lists(ctx, sg, new_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * Have aligned data from previous operation and/or current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * Note: will enter here only if (digest or finup) and aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (ctx->bufcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ctx->sg_len = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) sg_init_table(ctx->sgl, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) sg_set_buf(ctx->sgl, ctx->dd->xmit_buf, ctx->bufcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) sg_chain(ctx->sgl, 2, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ctx->sg = ctx->sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ctx->sg_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ctx->sg = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ctx->sg_len = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * s5p_hash_prepare_request() - prepare request for processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * @update: true if UPDATE op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * Note 1: we can have update flag _and_ final flag at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * Note 2: we enter here when digcnt > BUFLEN (=HASH_BLOCK_SIZE) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * either req->nbytes or ctx->bufcnt + req->nbytes is > BUFLEN or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * we have final op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) static int s5p_hash_prepare_request(struct ahash_request *req, bool update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) bool final = ctx->finup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) int xmit_len, hash_later, nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) nbytes = req->nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) nbytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ctx->total = nbytes + ctx->bufcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (!ctx->total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (nbytes && (!IS_ALIGNED(ctx->bufcnt, BUFLEN))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* bytes left from previous request, so fill up to BUFLEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) int len = BUFLEN - ctx->bufcnt % BUFLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (len > nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) len = nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, req->src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 0, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ctx->bufcnt += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) nbytes -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ctx->skip = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ctx->skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (ctx->bufcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) memcpy(ctx->dd->xmit_buf, ctx->buffer, ctx->bufcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) xmit_len = ctx->total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (final) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) hash_later = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (IS_ALIGNED(xmit_len, BUFLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) xmit_len -= BUFLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) xmit_len -= xmit_len & (BUFLEN - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) hash_later = ctx->total - xmit_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* copy hash_later bytes from end of req->src */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* previous bytes are in xmit_buf, so no overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) scatterwalk_map_and_copy(ctx->buffer, req->src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) req->nbytes - hash_later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) hash_later, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (xmit_len > BUFLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) ret = s5p_hash_prepare_sgs(ctx, req->src, nbytes - hash_later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) final);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* have buffered data only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (unlikely(!ctx->bufcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /* first update didn't fill up buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) scatterwalk_map_and_copy(ctx->dd->xmit_buf, req->src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 0, xmit_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sg_init_table(ctx->sgl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) sg_set_buf(ctx->sgl, ctx->dd->xmit_buf, xmit_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) ctx->sg = ctx->sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ctx->sg_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ctx->bufcnt = hash_later;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (!final)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ctx->total = xmit_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * s5p_hash_update_dma_stop() - unmap DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * @dd: secss device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * Unmap scatterlist ctx->sg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) static void s5p_hash_update_dma_stop(struct s5p_aes_dev *dd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) const struct s5p_hash_reqctx *ctx = ahash_request_ctx(dd->hash_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) dma_unmap_sg(dd->dev, ctx->sg, ctx->sg_len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) clear_bit(HASH_FLAGS_DMA_ACTIVE, &dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * s5p_hash_finish() - copy calculated digest to crypto layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static void s5p_hash_finish(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct s5p_aes_dev *dd = ctx->dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (ctx->digcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) s5p_hash_copy_result(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) dev_dbg(dd->dev, "hash_finish digcnt: %lld\n", ctx->digcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * s5p_hash_finish_req() - finish request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * @err: error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static void s5p_hash_finish_req(struct ahash_request *req, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct s5p_aes_dev *dd = ctx->dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (test_bit(HASH_FLAGS_SGS_COPIED, &dd->hash_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) free_pages((unsigned long)sg_virt(ctx->sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) get_order(ctx->sg->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (test_bit(HASH_FLAGS_SGS_ALLOCED, &dd->hash_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) kfree(ctx->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) ctx->sg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) dd->hash_flags &= ~(BIT(HASH_FLAGS_SGS_ALLOCED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) BIT(HASH_FLAGS_SGS_COPIED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (!err && !ctx->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) s5p_hash_read_msg(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (test_bit(HASH_FLAGS_FINAL, &dd->hash_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) s5p_hash_finish(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) spin_lock_irqsave(&dd->hash_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) dd->hash_flags &= ~(BIT(HASH_FLAGS_BUSY) | BIT(HASH_FLAGS_FINAL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) BIT(HASH_FLAGS_DMA_READY) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) BIT(HASH_FLAGS_OUTPUT_READY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) spin_unlock_irqrestore(&dd->hash_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (req->base.complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) req->base.complete(&req->base, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) * s5p_hash_handle_queue() - handle hash queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * @dd: device s5p_aes_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * If req!=NULL enqueue it on dd->queue, if FLAGS_BUSY is not set on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * device then processes the first request from the dd->queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * Returns: see s5p_hash_final below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static int s5p_hash_handle_queue(struct s5p_aes_dev *dd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct crypto_async_request *async_req, *backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct s5p_hash_reqctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) int err = 0, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) spin_lock_irqsave(&dd->hash_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) ret = ahash_enqueue_request(&dd->hash_queue, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (test_bit(HASH_FLAGS_BUSY, &dd->hash_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) spin_unlock_irqrestore(&dd->hash_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) backlog = crypto_get_backlog(&dd->hash_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) async_req = crypto_dequeue_request(&dd->hash_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (async_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) set_bit(HASH_FLAGS_BUSY, &dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) spin_unlock_irqrestore(&dd->hash_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (!async_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) backlog->complete(backlog, -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) req = ahash_request_cast(async_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) dd->hash_req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) err = s5p_hash_prepare_request(req, ctx->op_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (err || !ctx->total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) dev_dbg(dd->dev, "handling new req, op_update: %u, nbytes: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ctx->op_update, req->nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) s5p_ahash_dma_init(dd, SSS_HASHIN_INDEPENDENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (ctx->digcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) s5p_hash_write_iv(req); /* restore hash IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (ctx->op_update) { /* HASH_OP_UPDATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) err = s5p_hash_xmit_dma(dd, ctx->total, ctx->finup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (err != -EINPROGRESS && ctx->finup && !ctx->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /* no final() after finup() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) err = s5p_hash_xmit_dma(dd, ctx->total, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) } else { /* HASH_OP_FINAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) err = s5p_hash_xmit_dma(dd, ctx->total, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (err != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) /* hash_tasklet_cb will not finish it, so do it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) s5p_hash_finish_req(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * Execute next request immediately if there is anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * in queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) * s5p_hash_tasklet_cb() - hash tasklet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) * @data: ptr to s5p_aes_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) static void s5p_hash_tasklet_cb(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) struct s5p_aes_dev *dd = (struct s5p_aes_dev *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (!test_bit(HASH_FLAGS_BUSY, &dd->hash_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) s5p_hash_handle_queue(dd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (test_bit(HASH_FLAGS_DMA_READY, &dd->hash_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (test_and_clear_bit(HASH_FLAGS_DMA_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) &dd->hash_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) s5p_hash_update_dma_stop(dd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (test_and_clear_bit(HASH_FLAGS_OUTPUT_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) &dd->hash_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) /* hash or semi-hash ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) clear_bit(HASH_FLAGS_DMA_READY, &dd->hash_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /* finish curent request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) s5p_hash_finish_req(dd->hash_req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* If we are not busy, process next req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (!test_bit(HASH_FLAGS_BUSY, &dd->hash_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) s5p_hash_handle_queue(dd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * s5p_hash_enqueue() - enqueue request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * @op: operation UPDATE (true) or FINAL (false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * Returns: see s5p_hash_final below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static int s5p_hash_enqueue(struct ahash_request *req, bool op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) struct s5p_hash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) ctx->op_update = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) return s5p_hash_handle_queue(tctx->dd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * s5p_hash_update() - process the hash input data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * If request will fit in buffer, copy it and return immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * else enqueue it with OP_UPDATE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * Returns: see s5p_hash_final below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) static int s5p_hash_update(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (!req->nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (ctx->bufcnt + req->nbytes <= BUFLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, req->src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 0, req->nbytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) ctx->bufcnt += req->nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return s5p_hash_enqueue(req, true); /* HASH_OP_UPDATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * s5p_hash_final() - close up hash and calculate digest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * Note: in final req->src do not have any data, and req->nbytes can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) * non-zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * If there were no input data processed yet and the buffered hash data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * less than BUFLEN (64) then calculate the final hash immediately by using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * SW algorithm fallback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * Otherwise enqueues the current AHASH request with OP_FINAL operation op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * and finalize hash message in HW. Note that if digcnt!=0 then there were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * previous update op, so there are always some buffered bytes in ctx->buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * which means that ctx->bufcnt!=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) * 0 if the request has been processed immediately,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * -EINPROGRESS if the operation has been queued for later execution or is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) * to processing by HW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * -EBUSY if queue is full and request should be resubmitted later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) * other negative values denotes an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static int s5p_hash_final(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ctx->finup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (ctx->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return -EINVAL; /* uncompleted hash is not needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (!ctx->digcnt && ctx->bufcnt < BUFLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct s5p_hash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return crypto_shash_tfm_digest(tctx->fallback, ctx->buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) ctx->bufcnt, req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return s5p_hash_enqueue(req, false); /* HASH_OP_FINAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) * s5p_hash_finup() - process last req->src and calculate digest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * @req: AHASH request containing the last update data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * Return values: see s5p_hash_final above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) static int s5p_hash_finup(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) int err1, err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) ctx->finup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) err1 = s5p_hash_update(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (err1 == -EINPROGRESS || err1 == -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) return err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) * final() has to be always called to cleanup resources even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * update() failed, except EINPROGRESS or calculate digest for small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) err2 = s5p_hash_final(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return err1 ?: err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * s5p_hash_init() - initialize AHASH request contex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * Init async hash request context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static int s5p_hash_init(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct s5p_hash_ctx *tctx = crypto_ahash_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) ctx->dd = tctx->dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) ctx->error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) ctx->finup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) ctx->bufcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) ctx->digcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) ctx->total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) ctx->skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) dev_dbg(tctx->dd->dev, "init: digest size: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) crypto_ahash_digestsize(tfm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) switch (crypto_ahash_digestsize(tfm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) case MD5_DIGEST_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) ctx->engine = SSS_HASH_ENGINE_MD5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) ctx->nregs = HASH_MD5_MAX_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) case SHA1_DIGEST_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) ctx->engine = SSS_HASH_ENGINE_SHA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) ctx->nregs = HASH_SHA1_MAX_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) case SHA256_DIGEST_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) ctx->engine = SSS_HASH_ENGINE_SHA256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) ctx->nregs = HASH_SHA256_MAX_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * s5p_hash_digest - calculate digest from req->src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * Return values: see s5p_hash_final above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) static int s5p_hash_digest(struct ahash_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) return s5p_hash_init(req) ?: s5p_hash_finup(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * s5p_hash_cra_init_alg - init crypto alg transformation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) * @tfm: crypto transformation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) static int s5p_hash_cra_init_alg(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) struct s5p_hash_ctx *tctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) const char *alg_name = crypto_tfm_alg_name(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) tctx->dd = s5p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /* Allocate a fallback and abort if it failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) tctx->fallback = crypto_alloc_shash(alg_name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) CRYPTO_ALG_NEED_FALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (IS_ERR(tctx->fallback)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) pr_err("fallback alloc fails for '%s'\n", alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) return PTR_ERR(tctx->fallback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) sizeof(struct s5p_hash_reqctx) + BUFLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) * s5p_hash_cra_init - init crypto tfm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) * @tfm: crypto transformation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) static int s5p_hash_cra_init(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) return s5p_hash_cra_init_alg(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) * s5p_hash_cra_exit - exit crypto tfm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) * @tfm: crypto transformation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * free allocated fallback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) static void s5p_hash_cra_exit(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) struct s5p_hash_ctx *tctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) crypto_free_shash(tctx->fallback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) tctx->fallback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) * s5p_hash_export - export hash state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * @out: buffer for exported state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) static int s5p_hash_export(struct ahash_request *req, void *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) const struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) memcpy(out, ctx, sizeof(*ctx) + ctx->bufcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * s5p_hash_import - import hash state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) * @req: AHASH request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) * @in: buffer with state to be imported from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) static int s5p_hash_import(struct ahash_request *req, const void *in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) struct s5p_hash_ctx *tctx = crypto_ahash_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) const struct s5p_hash_reqctx *ctx_in = in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) memcpy(ctx, in, sizeof(*ctx) + BUFLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (ctx_in->bufcnt > BUFLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) ctx->error = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) ctx->dd = tctx->dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) ctx->error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static struct ahash_alg algs_sha1_md5_sha256[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) .init = s5p_hash_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) .update = s5p_hash_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) .final = s5p_hash_final,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) .finup = s5p_hash_finup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) .digest = s5p_hash_digest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) .export = s5p_hash_export,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) .import = s5p_hash_import,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) .halg.statesize = sizeof(struct s5p_hash_reqctx) + BUFLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .halg.digestsize = SHA1_DIGEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .halg.base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) .cra_name = "sha1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) .cra_driver_name = "exynos-sha1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) CRYPTO_ALG_NEED_FALLBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) .cra_blocksize = HASH_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) .cra_ctxsize = sizeof(struct s5p_hash_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) .cra_alignmask = SSS_HASH_DMA_ALIGN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) .cra_init = s5p_hash_cra_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) .cra_exit = s5p_hash_cra_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .init = s5p_hash_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) .update = s5p_hash_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) .final = s5p_hash_final,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) .finup = s5p_hash_finup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .digest = s5p_hash_digest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) .export = s5p_hash_export,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .import = s5p_hash_import,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) .halg.statesize = sizeof(struct s5p_hash_reqctx) + BUFLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .halg.digestsize = MD5_DIGEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .halg.base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .cra_name = "md5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .cra_driver_name = "exynos-md5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) CRYPTO_ALG_NEED_FALLBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .cra_blocksize = HASH_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) .cra_ctxsize = sizeof(struct s5p_hash_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) .cra_alignmask = SSS_HASH_DMA_ALIGN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .cra_init = s5p_hash_cra_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) .cra_exit = s5p_hash_cra_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .init = s5p_hash_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .update = s5p_hash_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .final = s5p_hash_final,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .finup = s5p_hash_finup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) .digest = s5p_hash_digest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) .export = s5p_hash_export,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .import = s5p_hash_import,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) .halg.statesize = sizeof(struct s5p_hash_reqctx) + BUFLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) .halg.digestsize = SHA256_DIGEST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) .halg.base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .cra_name = "sha256",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) .cra_driver_name = "exynos-sha256",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) .cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) CRYPTO_ALG_NEED_FALLBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) .cra_blocksize = HASH_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) .cra_ctxsize = sizeof(struct s5p_hash_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) .cra_alignmask = SSS_HASH_DMA_ALIGN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) .cra_init = s5p_hash_cra_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) .cra_exit = s5p_hash_cra_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static void s5p_set_aes(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) const u8 *key, const u8 *iv, const u8 *ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) unsigned int keylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) void __iomem *keystart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (iv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) memcpy_toio(dev->aes_ioaddr + SSS_REG_AES_IV_DATA(0), iv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (ctr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) memcpy_toio(dev->aes_ioaddr + SSS_REG_AES_CNT_DATA(0), ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) AES_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (keylen == AES_KEYSIZE_256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) keystart = dev->aes_ioaddr + SSS_REG_AES_KEY_DATA(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) else if (keylen == AES_KEYSIZE_192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) keystart = dev->aes_ioaddr + SSS_REG_AES_KEY_DATA(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) keystart = dev->aes_ioaddr + SSS_REG_AES_KEY_DATA(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) memcpy_toio(keystart, key, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) static bool s5p_is_sg_aligned(struct scatterlist *sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) while (sg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (!IS_ALIGNED(sg->length, AES_BLOCK_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) static int s5p_set_indata_start(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) dev->sg_src_cpy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) sg = req->src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) if (!s5p_is_sg_aligned(sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) dev_dbg(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) "At least one unaligned source scatter list, making a copy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) err = s5p_make_sg_cpy(dev, sg, &dev->sg_src_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) sg = dev->sg_src_cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) err = s5p_set_indata(dev, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) s5p_free_sg_cpy(dev, &dev->sg_src_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) static int s5p_set_outdata_start(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) dev->sg_dst_cpy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) sg = req->dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (!s5p_is_sg_aligned(sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) dev_dbg(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) "At least one unaligned dest scatter list, making a copy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) err = s5p_make_sg_cpy(dev, sg, &dev->sg_dst_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) sg = dev->sg_dst_cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) err = s5p_set_outdata(dev, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) s5p_free_sg_cpy(dev, &dev->sg_dst_cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) struct skcipher_request *req = dev->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) u32 aes_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) u8 *iv, *ctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) /* This sets bit [13:12] to 00, which selects 128-bit counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) aes_control = SSS_AES_KEY_CHANGE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (mode & FLAGS_AES_DECRYPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) aes_control |= SSS_AES_MODE_DECRYPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) aes_control |= SSS_AES_CHAIN_MODE_CBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) iv = req->iv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) ctr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) } else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) aes_control |= SSS_AES_CHAIN_MODE_CTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) iv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) ctr = req->iv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) iv = NULL; /* AES_ECB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) ctr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (dev->ctx->keylen == AES_KEYSIZE_192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) aes_control |= SSS_AES_KEY_SIZE_192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) else if (dev->ctx->keylen == AES_KEYSIZE_256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) aes_control |= SSS_AES_KEY_SIZE_256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) aes_control |= SSS_AES_FIFO_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) /* as a variant it is possible to use byte swapping on DMA side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) aes_control |= SSS_AES_BYTESWAP_DI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) | SSS_AES_BYTESWAP_DO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) | SSS_AES_BYTESWAP_IV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) | SSS_AES_BYTESWAP_KEY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) | SSS_AES_BYTESWAP_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) spin_lock_irqsave(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) SSS_WRITE(dev, FCINTENCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) SSS_FCINTENCLR_BTDMAINTENCLR | SSS_FCINTENCLR_BRDMAINTENCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) SSS_WRITE(dev, FCFIFOCTRL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) err = s5p_set_indata_start(dev, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) goto indata_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) err = s5p_set_outdata_start(dev, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) goto outdata_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) SSS_AES_WRITE(dev, AES_CONTROL, aes_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) s5p_set_aes(dev, dev->ctx->aes_key, iv, ctr, dev->ctx->keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) s5p_set_dma_indata(dev, dev->sg_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) s5p_set_dma_outdata(dev, dev->sg_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) SSS_WRITE(dev, FCINTENSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) SSS_FCINTENSET_BTDMAINTENSET | SSS_FCINTENSET_BRDMAINTENSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) outdata_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) s5p_unset_indata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) indata_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) s5p_sg_done(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) dev->busy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) s5p_aes_complete(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) static void s5p_tasklet_cb(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) struct s5p_aes_dev *dev = (struct s5p_aes_dev *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct crypto_async_request *async_req, *backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) struct s5p_aes_reqctx *reqctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) spin_lock_irqsave(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) backlog = crypto_get_backlog(&dev->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) async_req = crypto_dequeue_request(&dev->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (!async_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) dev->busy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) backlog->complete(backlog, -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) dev->req = skcipher_request_cast(async_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) dev->ctx = crypto_tfm_ctx(dev->req->base.tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) reqctx = skcipher_request_ctx(dev->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) s5p_aes_crypt_start(dev, reqctx->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) static int s5p_aes_handle_req(struct s5p_aes_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) spin_lock_irqsave(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) err = crypto_enqueue_request(&dev->queue, &req->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (dev->busy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) dev->busy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) spin_unlock_irqrestore(&dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) tasklet_schedule(&dev->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) static int s5p_aes_crypt(struct skcipher_request *req, unsigned long mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) struct s5p_aes_reqctx *reqctx = skcipher_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) struct s5p_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct s5p_aes_dev *dev = ctx->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (!req->cryptlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (!IS_ALIGNED(req->cryptlen, AES_BLOCK_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ((mode & FLAGS_AES_MODE_MASK) != FLAGS_AES_CTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) dev_dbg(dev->dev, "request size is not exact amount of AES blocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) reqctx->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) return s5p_aes_handle_req(dev, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static int s5p_aes_setkey(struct crypto_skcipher *cipher,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) const u8 *key, unsigned int keylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (keylen != AES_KEYSIZE_128 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) keylen != AES_KEYSIZE_192 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) keylen != AES_KEYSIZE_256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) memcpy(ctx->aes_key, key, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) ctx->keylen = keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static int s5p_aes_ecb_encrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) return s5p_aes_crypt(req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) static int s5p_aes_ecb_decrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) return s5p_aes_crypt(req, FLAGS_AES_DECRYPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) static int s5p_aes_cbc_encrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) return s5p_aes_crypt(req, FLAGS_AES_CBC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) static int s5p_aes_cbc_decrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) return s5p_aes_crypt(req, FLAGS_AES_DECRYPT | FLAGS_AES_CBC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static int s5p_aes_ctr_crypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return s5p_aes_crypt(req, FLAGS_AES_CTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static int s5p_aes_init_tfm(struct crypto_skcipher *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) struct s5p_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) ctx->dev = s5p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) crypto_skcipher_set_reqsize(tfm, sizeof(struct s5p_aes_reqctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) static struct skcipher_alg algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) .base.cra_name = "ecb(aes)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) .base.cra_driver_name = "ecb-aes-s5p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) .base.cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) .base.cra_flags = CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) CRYPTO_ALG_KERN_DRIVER_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) .base.cra_blocksize = AES_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) .base.cra_ctxsize = sizeof(struct s5p_aes_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) .base.cra_alignmask = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) .base.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) .min_keysize = AES_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) .max_keysize = AES_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) .setkey = s5p_aes_setkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) .encrypt = s5p_aes_ecb_encrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) .decrypt = s5p_aes_ecb_decrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) .init = s5p_aes_init_tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) .base.cra_name = "cbc(aes)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) .base.cra_driver_name = "cbc-aes-s5p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) .base.cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) .base.cra_flags = CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) CRYPTO_ALG_KERN_DRIVER_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) .base.cra_blocksize = AES_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) .base.cra_ctxsize = sizeof(struct s5p_aes_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) .base.cra_alignmask = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) .base.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) .min_keysize = AES_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) .max_keysize = AES_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) .ivsize = AES_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) .setkey = s5p_aes_setkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) .encrypt = s5p_aes_cbc_encrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) .decrypt = s5p_aes_cbc_decrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) .init = s5p_aes_init_tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) .base.cra_name = "ctr(aes)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) .base.cra_driver_name = "ctr-aes-s5p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) .base.cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) .base.cra_flags = CRYPTO_ALG_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) CRYPTO_ALG_KERN_DRIVER_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) .base.cra_blocksize = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) .base.cra_ctxsize = sizeof(struct s5p_aes_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) .base.cra_alignmask = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) .base.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) .min_keysize = AES_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) .max_keysize = AES_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) .ivsize = AES_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) .setkey = s5p_aes_setkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) .encrypt = s5p_aes_ctr_crypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) .decrypt = s5p_aes_ctr_crypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) .init = s5p_aes_init_tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static int s5p_aes_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) int i, j, err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) const struct samsung_aes_variant *variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) struct s5p_aes_dev *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) unsigned int hash_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (s5p_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) variant = find_s5p_sss_version(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * Note: HASH and PRNG uses the same registers in secss, avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) * overwrite each other. This will drop HASH when CONFIG_EXYNOS_RNG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) * is enabled in config. We need larger size for HASH registers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) * secss, current describe only AES/DES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (IS_ENABLED(CONFIG_CRYPTO_DEV_EXYNOS_HASH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (variant == &exynos_aes_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) res->end += 0x300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) pdata->use_hash = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) pdata->res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (IS_ERR(pdata->ioaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (!pdata->use_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return PTR_ERR(pdata->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) /* try AES without HASH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) res->end -= 0x300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) pdata->use_hash = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (IS_ERR(pdata->ioaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) return PTR_ERR(pdata->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) pdata->clk = devm_clk_get(dev, variant->clk_names[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (IS_ERR(pdata->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return dev_err_probe(dev, PTR_ERR(pdata->clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) "failed to find secss clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) variant->clk_names[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) err = clk_prepare_enable(pdata->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) dev_err(dev, "Enabling clock %s failed, err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) variant->clk_names[0], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) if (variant->clk_names[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) pdata->pclk = devm_clk_get(dev, variant->clk_names[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) if (IS_ERR(pdata->pclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) err = dev_err_probe(dev, PTR_ERR(pdata->pclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) "failed to find clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) variant->clk_names[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) err = clk_prepare_enable(pdata->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) dev_err(dev, "Enabling clock %s failed, err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) variant->clk_names[0], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) pdata->pclk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) spin_lock_init(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) spin_lock_init(&pdata->hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) pdata->aes_ioaddr = pdata->ioaddr + variant->aes_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) pdata->io_hash_base = pdata->ioaddr + variant->hash_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) pdata->irq_fc = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (pdata->irq_fc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) err = pdata->irq_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) dev_warn(dev, "feed control interrupt is not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) goto err_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) err = devm_request_threaded_irq(dev, pdata->irq_fc, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) s5p_aes_interrupt, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) pdev->name, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) dev_warn(dev, "feed control interrupt is not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) goto err_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) pdata->busy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) pdata->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) platform_set_drvdata(pdev, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) s5p_dev = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) tasklet_init(&pdata->tasklet, s5p_tasklet_cb, (unsigned long)pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) crypto_init_queue(&pdata->queue, CRYPTO_QUEUE_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) for (i = 0; i < ARRAY_SIZE(algs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) err = crypto_register_skcipher(&algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) goto err_algs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if (pdata->use_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) tasklet_init(&pdata->hash_tasklet, s5p_hash_tasklet_cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) (unsigned long)pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) crypto_init_queue(&pdata->hash_queue, SSS_HASH_QUEUE_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) for (hash_i = 0; hash_i < ARRAY_SIZE(algs_sha1_md5_sha256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) hash_i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) struct ahash_alg *alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) alg = &algs_sha1_md5_sha256[hash_i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) err = crypto_register_ahash(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) dev_err(dev, "can't register '%s': %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) alg->halg.base.cra_driver_name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) goto err_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) dev_info(dev, "s5p-sss driver registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) err_hash:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) for (j = hash_i - 1; j >= 0; j--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) crypto_unregister_ahash(&algs_sha1_md5_sha256[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) tasklet_kill(&pdata->hash_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) res->end -= 0x300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) err_algs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (i < ARRAY_SIZE(algs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) dev_err(dev, "can't register '%s': %d\n", algs[i].base.cra_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) for (j = 0; j < i; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) crypto_unregister_skcipher(&algs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) tasklet_kill(&pdata->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) err_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) clk_disable_unprepare(pdata->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) clk_disable_unprepare(pdata->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) s5p_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) static int s5p_aes_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) struct s5p_aes_dev *pdata = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) for (i = 0; i < ARRAY_SIZE(algs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) crypto_unregister_skcipher(&algs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) tasklet_kill(&pdata->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) if (pdata->use_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) for (i = ARRAY_SIZE(algs_sha1_md5_sha256) - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) crypto_unregister_ahash(&algs_sha1_md5_sha256[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) pdata->res->end -= 0x300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) tasklet_kill(&pdata->hash_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) pdata->use_hash = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) clk_disable_unprepare(pdata->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) clk_disable_unprepare(pdata->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) s5p_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) static struct platform_driver s5p_aes_crypto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) .probe = s5p_aes_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) .remove = s5p_aes_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) .name = "s5p-secss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) .of_match_table = s5p_sss_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) module_platform_driver(s5p_aes_crypto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) MODULE_DESCRIPTION("S5PV210 AES hw acceleration support.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) MODULE_AUTHOR("Vladimir Zapolskiy <vzapolskiy@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) MODULE_AUTHOR("Kamil Konieczny <k.konieczny@partner.samsung.com>");