* [PATCH 2/4] crypto: prepare to allow multiple digest driver
2015-03-24 9:19 ` [PATCH 1/4] command: digest: only set the key when specified Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-24 9:19 ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 3/4] crypto: sha1: switch to linux implementation Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 4/4] arm: crypto: add sha1 assembly support Jean-Christophe PLAGNIOL-VILLARD
2 siblings, 0 replies; 5+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-24 9:19 UTC (permalink / raw)
To: barebox
This will allow to have hw driver or asm optimised driver.
Use a priority level to determine which one to use at runtime.
The generic one will be 0.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/configs/at91rm9200ek_defconfig | 4 +--
arch/arm/configs/highbank_defconfig | 4 +--
arch/arm/configs/mioa701_defconfig | 2 +-
arch/arm/configs/module-mb7707_defconfig | 4 +--
arch/arm/configs/nhk8815_defconfig | 2 +-
arch/arm/configs/phytec-phycard-omap3_defconfig | 6 ++--
arch/arm/configs/rpi_defconfig | 4 +--
arch/arm/configs/versatilepb_arm1176_defconfig | 4 +--
arch/arm/configs/versatilepb_defconfig | 4 +--
arch/arm/configs/vexpress_ca9_defconfig | 4 +--
arch/arm/configs/vexpress_defconfig | 4 +--
arch/arm/configs/virt2real_defconfig | 4 +--
arch/arm/configs/zylonite310_defconfig | 2 +-
arch/mips/configs/img-ci20_defconfig | 6 ++--
arch/mips/configs/ritmix-rzx50_defconfig | 6 ++--
arch/mips/configs/tplink-mr3020_defconfig | 4 +--
crypto/Kconfig | 40 +++++++++++++++++++++----
crypto/Makefile | 14 ++++-----
crypto/digest.c | 31 +++++++++++--------
crypto/hmac.c | 15 ++++++----
crypto/md5.c | 9 ++++--
crypto/sha1.c | 9 ++++--
crypto/sha2.c | 17 ++++++++---
crypto/sha4.c | 17 ++++++++---
{crypto => include/crypto}/internal.h | 0
include/digest.h | 12 ++++++--
26 files changed, 150 insertions(+), 78 deletions(-)
rename {crypto => include/crypto}/internal.h (100%)
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index 54e3b1d..03fca04 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -76,5 +76,5 @@ CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_TRIGGERS=y
CONFIG_FS_CRAMFS=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/highbank_defconfig b/arch/arm/configs/highbank_defconfig
index cf42d29..8c965c8 100644
--- a/arch/arm/configs/highbank_defconfig
+++ b/arch/arm/configs/highbank_defconfig
@@ -59,5 +59,5 @@ CONFIG_DISK=y
CONFIG_DISK_AHCI=y
CONFIG_GPIO_PL061=y
CONFIG_FS_TFTP=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/mioa701_defconfig b/arch/arm/configs/mioa701_defconfig
index d405edf..cc4587c 100644
--- a/arch/arm/configs/mioa701_defconfig
+++ b/arch/arm/configs/mioa701_defconfig
@@ -104,4 +104,4 @@ CONFIG_FS_UBIFS_COMPRESSION_ZLIB=y
CONFIG_BZLIB=y
CONFIG_BMP=y
CONFIG_PNG=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/module-mb7707_defconfig b/arch/arm/configs/module-mb7707_defconfig
index 843dd59..83a798b 100644
--- a/arch/arm/configs/module-mb7707_defconfig
+++ b/arch/arm/configs/module-mb7707_defconfig
@@ -45,5 +45,5 @@ CONFIG_USB_HOST=y
CONFIG_USB_EHCI=y
CONFIG_USB_STORAGE=y
CONFIG_CLOCKSOURCE_DUMMY=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index dcb00c0..46c3a68 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -55,4 +55,4 @@ CONFIG_MTD_NAND_NOMADIK=y
CONFIG_UBI=y
CONFIG_FS_CRAMFS=y
CONFIG_MD5=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/phytec-phycard-omap3_defconfig b/arch/arm/configs/phytec-phycard-omap3_defconfig
index aefc78d..a2564d4 100644
--- a/arch/arm/configs/phytec-phycard-omap3_defconfig
+++ b/arch/arm/configs/phytec-phycard-omap3_defconfig
@@ -173,6 +173,6 @@ CONFIG_CRC32=y
CONFIG_CRC16=y
CONFIG_DIGEST=y
CONFIG_MD5=y
-CONFIG_SHA1=y
-CONFIG_SHA224=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA224_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig
index c6b2c50..25770a0 100644
--- a/arch/arm/configs/rpi_defconfig
+++ b/arch/arm/configs/rpi_defconfig
@@ -64,5 +64,5 @@ CONFIG_FS_EXT4=y
CONFIG_FS_FAT=y
CONFIG_FS_FAT_WRITE=y
CONFIG_FS_FAT_LFN=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/versatilepb_arm1176_defconfig b/arch/arm/configs/versatilepb_arm1176_defconfig
index ca0ab36..cefdb29 100644
--- a/arch/arm/configs/versatilepb_arm1176_defconfig
+++ b/arch/arm/configs/versatilepb_arm1176_defconfig
@@ -95,5 +95,5 @@ CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y
CONFIG_PNG=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
index 54a6fec..0876824 100644
--- a/arch/arm/configs/versatilepb_defconfig
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -81,5 +81,5 @@ CONFIG_FS_CRAMFS=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/vexpress_ca9_defconfig b/arch/arm/configs/vexpress_ca9_defconfig
index 84171c4..c5ad315 100644
--- a/arch/arm/configs/vexpress_ca9_defconfig
+++ b/arch/arm/configs/vexpress_ca9_defconfig
@@ -58,5 +58,5 @@ CONFIG_DRIVER_CFI=y
# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set
CONFIG_FS_TFTP=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
index c7928c4..beea11a 100644
--- a/arch/arm/configs/vexpress_defconfig
+++ b/arch/arm/configs/vexpress_defconfig
@@ -57,5 +57,5 @@ CONFIG_DRIVER_CFI=y
# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set
CONFIG_FS_TFTP=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/virt2real_defconfig b/arch/arm/configs/virt2real_defconfig
index a81d18b..0c686ca 100644
--- a/arch/arm/configs/virt2real_defconfig
+++ b/arch/arm/configs/virt2real_defconfig
@@ -45,5 +45,5 @@ CONFIG_DRIVER_SERIAL_NS16550=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_GPIO_OF=y
-CONFIG_SHA1=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/configs/zylonite310_defconfig b/arch/arm/configs/zylonite310_defconfig
index 77e4f84..fa6587c 100644
--- a/arch/arm/configs/zylonite310_defconfig
+++ b/arch/arm/configs/zylonite310_defconfig
@@ -114,4 +114,4 @@ CONFIG_FS_UBIFS_COMPRESSION_ZLIB=y
CONFIG_BZLIB=y
CONFIG_BMP=y
CONFIG_PNG=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/mips/configs/img-ci20_defconfig b/arch/mips/configs/img-ci20_defconfig
index 56235c4..6702c88 100644
--- a/arch/mips/configs/img-ci20_defconfig
+++ b/arch/mips/configs/img-ci20_defconfig
@@ -37,6 +37,6 @@ CONFIG_OFDEVICE=y
# CONFIG_SPI is not set
CONFIG_CLOCKSOURCE_DUMMY=y
CONFIG_CLOCKSOURCE_DUMMY_RATE=3500
-CONFIG_SHA1=y
-CONFIG_SHA224=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA224_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/mips/configs/ritmix-rzx50_defconfig b/arch/mips/configs/ritmix-rzx50_defconfig
index 0814883..eedb329 100644
--- a/arch/mips/configs/ritmix-rzx50_defconfig
+++ b/arch/mips/configs/ritmix-rzx50_defconfig
@@ -46,6 +46,6 @@ CONFIG_LED_TRIGGERS=y
CONFIG_GPIO_JZ4740=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_JZ4740=y
-CONFIG_SHA1=y
-CONFIG_SHA224=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA224_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/mips/configs/tplink-mr3020_defconfig b/arch/mips/configs/tplink-mr3020_defconfig
index d249919..9f81ce3 100644
--- a/arch/mips/configs/tplink-mr3020_defconfig
+++ b/arch/mips/configs/tplink-mr3020_defconfig
@@ -30,5 +30,5 @@ CONFIG_MTD=y
# CONFIG_MTD_OOB_DEVICE is not set
CONFIG_MTD_M25P80=y
CONFIG_MD5=y
-CONFIG_SHA224=y
-CONFIG_SHA256=y
+CONFIG_DIGEST_SHA224_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/crypto/Kconfig b/crypto/Kconfig
index b721e30..5a69236 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -13,25 +13,53 @@ menuconfig DIGEST
if DIGEST
config MD5
- bool "MD5"
+ bool
config SHA1
- bool "SHA1"
+ bool
config SHA224
- bool "SHA224"
+ bool
config SHA256
- bool "SHA256"
+ bool
config SHA384
- bool "SHA384"
+ bool
config SHA512
- bool "SHA512"
+ bool
config DIGEST_HMAC
+ bool
+
+config DIGEST_MD5_GENERIC
+ bool "MD5"
+ select MD5
+
+config DIGEST_SHA1_GENERIC
+ bool "SHA1"
+ select SHA1
+
+config DIGEST_SHA224_GENERIC
+ bool "SHA224"
+ select SHA224
+
+config DIGEST_SHA256_GENERIC
+ bool "SHA256"
+ select SHA256
+
+config DIGEST_SHA384_GENERIC
+ bool "SHA384"
+ select SHA384
+
+config DIGEST_SHA512_GENERIC
+ bool "SHA512"
+ select SHA512
+
+config DIGEST_HMAC_GENERIC
bool "HMAC"
+ select DIGEST_HMAC
endif
diff --git a/crypto/Makefile b/crypto/Makefile
index 0bb67d5..f39de71 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -2,12 +2,12 @@ obj-$(CONFIG_CRC32) += crc32.o
obj-$(CONFIG_CRC16) += crc16.o
obj-$(CONFIG_CRC7) += crc7.o
obj-$(CONFIG_DIGEST) += digest.o
-obj-$(CONFIG_DIGEST_HMAC) += hmac.o
-obj-$(CONFIG_MD5) += md5.o
-obj-$(CONFIG_SHA1) += sha1.o
-obj-$(CONFIG_SHA224) += sha2.o
-obj-$(CONFIG_SHA256) += sha2.o
-obj-$(CONFIG_SHA384) += sha4.o
-obj-$(CONFIG_SHA512) += sha4.o
+obj-$(CONFIG_DIGEST_HMAC_GENERIC) += hmac.o
+obj-$(CONFIG_DIGEST_MD5_GENERIC) += md5.o
+obj-$(CONFIG_DIGEST_SHA1_GENERIC) += sha1.o
+obj-$(CONFIG_DIGEST_SHA224_GENERIC) += sha2.o
+obj-$(CONFIG_DIGEST_SHA256_GENERIC) += sha2.o
+obj-$(CONFIG_DIGEST_SHA384_GENERIC) += sha4.o
+obj-$(CONFIG_DIGEST_SHA512_GENERIC) += sha4.o
obj-$(CONFIG_CRYPTO_PBKDF2) += pbkdf2.o
diff --git a/crypto/digest.c b/crypto/digest.c
index 047131b..03dacab 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -25,8 +25,7 @@
#include <errno.h>
#include <module.h>
#include <linux/err.h>
-
-#include "internal.h"
+#include <crypto/internal.h>
static LIST_HEAD(digests);
@@ -78,7 +77,7 @@ int digest_generic_digest(struct digest *d, const void *data,
int digest_algo_register(struct digest_algo *d)
{
- if (!d || !d->name || !d->update || !d->final || !d->verify ||
+ if (!d || !d->base.name || !d->update || !d->final || !d->verify ||
d->length < 1)
return -EINVAL;
@@ -91,9 +90,6 @@ int digest_algo_register(struct digest_algo *d)
if (!d->free)
d->free = dummy_free;
- if (digest_algo_get_by_name(d->name))
- return -EEXIST;
-
list_add_tail(&d->list, &digests);
return 0;
@@ -111,25 +107,36 @@ EXPORT_SYMBOL(digest_algo_unregister);
static struct digest_algo *digest_algo_get_by_name(const char *name)
{
- struct digest_algo *d;
+ struct digest_algo *d = NULL;
+ struct digest_algo *tmp;
+ int priority = -1;
if (!name)
return NULL;
- list_for_each_entry(d, &digests, list) {
- if(strcmp(d->name, name) == 0)
- return d;
+ list_for_each_entry(tmp, &digests, list) {
+ if (strcmp(tmp->base.name, name) != 0)
+ continue;
+
+ if (tmp->base.priority <= priority)
+ continue;
+
+ d = tmp;
+ priority = tmp->base.priority;
}
- return NULL;
+ return d;
}
void digest_algo_prints(const char *prefix)
{
struct digest_algo* d;
+ printf("%s%-15s\t%-20s\t%-15s\n", prefix, "name", "driver", "priority");
+ printf("%s--------------------------------------------------\n", prefix);
list_for_each_entry(d, &digests, list) {
- printf("%s%s\n", prefix, d->name);
+ printf("%s%-15s\t%-20s\t%d\n", prefix, d->base.name,
+ d->base.driver_name, d->base.priority);
}
}
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 4c6a703..bad8bbf 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -7,8 +7,7 @@
#include <common.h>
#include <digest.h>
#include <malloc.h>
-
-#include "internal.h"
+#include <crypto/internal.h>
struct digest_hmac {
char *name;
@@ -145,7 +144,10 @@ err:
}
struct digest_algo hmac_algo = {
- .flags = DIGEST_ALGO_NEED_KEY,
+ .base = {
+ .priority = 0,
+ .flags = DIGEST_ALGO_NEED_KEY,
+ },
.alloc = digest_hmac_alloc,
.init = digest_hmac_init,
.update = digest_hmac_update,
@@ -160,16 +162,19 @@ struct digest_algo hmac_algo = {
int digest_hmac_register(struct digest_algo *algo, unsigned int pad_length)
{
struct digest_hmac *dh;
+ char *name;
if (!algo || !pad_length)
return -EINVAL;
+ name = algo->base.name;
dh = xzalloc(sizeof(*dh));
- dh->name = xstrdup(algo->name);
+ dh->name = xstrdup(name);
dh->pad_length = pad_length;
dh->algo = hmac_algo;
dh->algo.length = algo->length;
- dh->algo.name = asprintf("hmac(%s)", algo->name);
+ dh->algo.base.name = asprintf("hmac(%s)", name);
+ dh->algo.base.driver_name = asprintf("hmac(%s)-generic", name);
return digest_algo_register(&dh->algo);
}
diff --git a/crypto/md5.c b/crypto/md5.c
index b7ad6f2..74c9b70 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -28,8 +28,7 @@
#include <common.h>
#include <digest.h>
#include <init.h>
-
-#include "internal.h"
+#include <crypto/internal.h>
struct MD5Context {
__u32 buf[4];
@@ -290,7 +289,11 @@ static int digest_md5_final(struct digest *d, unsigned char *md)
}
static struct digest_algo md5 = {
- .name = "md5",
+ .base = {
+ .name = "md5",
+ .driver_name = "md5-generic",
+ .priority = 0,
+ },
.init = digest_md5_init,
.update = digest_md5_update,
.final = digest_md5_final,
diff --git a/crypto/sha1.c b/crypto/sha1.c
index b108f8a..a2ca191 100644
--- a/crypto/sha1.c
+++ b/crypto/sha1.c
@@ -26,7 +26,7 @@
#include <linux/string.h>
#include <asm/byteorder.h>
-#include "internal.h"
+#include <crypto/internal.h>
#define SHA1_SUM_POS -0x20
#define SHA1_SUM_LEN 20
@@ -311,7 +311,12 @@ static int digest_sha1_final(struct digest *d, unsigned char *md)
}
static struct digest_algo m = {
- .name = "sha1",
+ .base = {
+ .name = "sha1",
+ .driver_name = "sha1-generic",
+ .priority = 0,
+ },
+
.init = digest_sha1_init,
.update = digest_sha1_update,
.final = digest_sha1_final,
diff --git a/crypto/sha2.c b/crypto/sha2.c
index 375a40e..42c40da 100644
--- a/crypto/sha2.c
+++ b/crypto/sha2.c
@@ -20,8 +20,7 @@
#include <init.h>
#include <linux/string.h>
#include <asm/byteorder.h>
-
-#include "internal.h"
+#include <crypto/internal.h>
#define SHA224_SUM_LEN 28
#define SHA256_SUM_LEN 32
@@ -300,7 +299,12 @@ static int digest_sha224_init(struct digest *d)
}
static struct digest_algo m224 = {
- .name = "sha224",
+ .base = {
+ .name = "sha224",
+ .driver_name = "sha224-generic",
+ .priority = 0,
+ },
+
.init = digest_sha224_init,
.update = digest_sha2_update,
.final = digest_sha2_final,
@@ -332,7 +336,12 @@ static int digest_sha256_init(struct digest *d)
}
static struct digest_algo m256 = {
- .name = "sha256",
+ .base = {
+ .name = "sha256",
+ .driver_name = "sha256-generic",
+ .priority = 0,
+ },
+
.init = digest_sha256_init,
.update = digest_sha2_update,
.final = digest_sha2_final,
diff --git a/crypto/sha4.c b/crypto/sha4.c
index 1b91e7f..cb62d1d 100644
--- a/crypto/sha4.c
+++ b/crypto/sha4.c
@@ -28,8 +28,7 @@
#include <init.h>
#include <linux/string.h>
#include <asm/byteorder.h>
-
-#include "internal.h"
+#include <crypto/internal.h>
#define SHA384_SUM_LEN 48
#define SHA512_SUM_LEN 64
@@ -305,7 +304,12 @@ static int digest_sha384_init(struct digest *d)
}
static struct digest_algo m384 = {
- .name = "sha384",
+ .base = {
+ .name = "sha384",
+ .driver_name = "sha384-generic",
+ .priority = 0,
+ },
+
.init = digest_sha384_init,
.update = digest_sha4_update,
.final = digest_sha4_final,
@@ -338,7 +342,12 @@ static int digest_sha512_init(struct digest *d)
}
static struct digest_algo m512 = {
- .name = "sha512",
+ .base = {
+ .name = "sha512",
+ .driver_name = "sha512-generic",
+ .priority = 0,
+ },
+
.init = digest_sha512_init,
.update = digest_sha4_update,
.final = digest_sha4_final,
diff --git a/crypto/internal.h b/include/crypto/internal.h
similarity index 100%
rename from crypto/internal.h
rename to include/crypto/internal.h
diff --git a/include/digest.h b/include/digest.h
index 85c4da3..c1221fc 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -23,10 +23,16 @@
struct digest;
-struct digest_algo {
+struct crypto_alg {
char *name;
+ char *driver_name;
+ int priority;
#define DIGEST_ALGO_NEED_KEY (1 << 0)
unsigned int flags;
+};
+
+struct digest_algo {
+ struct crypto_alg base;
int (*alloc)(struct digest *d);
void (*free)(struct digest *d);
@@ -112,12 +118,12 @@ static inline int digest_set_key(struct digest *d, const unsigned char *key,
static inline int digest_is_flags(struct digest *d, unsigned int flags)
{
- return d->algo->flags & flags;
+ return d->algo->base.flags & flags;
}
static inline const char *digest_name(struct digest *d)
{
- return d->algo->name;
+ return d->algo->base.name;
}
#endif /* __SH_ST_DEVICES_H__ */
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] crypto: sha1: switch to linux implementation
2015-03-24 9:19 ` [PATCH 1/4] command: digest: only set the key when specified Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 2/4] crypto: prepare to allow multiple digest driver Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-24 9:19 ` Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 4/4] arm: crypto: add sha1 assembly support Jean-Christophe PLAGNIOL-VILLARD
2 siblings, 0 replies; 5+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-24 9:19 UTC (permalink / raw)
To: barebox
current implementation
$ ls -al build/versatilpb/arch/arm/pbl/zbarebox.bin
-rw-r--r-- 1 root root 211095 Mar 24 13:21 build/versatilpb/arch/arm/pbl/zbarebox.bin
linux generic implementation
$ ls -al build/versatilpb/arch/arm/pbl/zbarebox.bin
-rw-r--r-- 1 root root 210829 Mar 24 13:21 build/versatilpb/arch/arm/pbl/zbarebox.bin
on a compressed lzo barebox we will 266 bytes
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
crypto/sha1.c | 650 ++++++++++++++++++++++++---------------------------
include/crypto/sha.h | 95 ++++++++
include/digest.h | 5 +
3 files changed, 411 insertions(+), 339 deletions(-)
rewrite crypto/sha1.c (90%)
create mode 100644 include/crypto/sha.h
diff --git a/crypto/sha1.c b/crypto/sha1.c
dissimilarity index 90%
index a2ca191..68830ac 100644
--- a/crypto/sha1.c
+++ b/crypto/sha1.c
@@ -1,339 +1,311 @@
-/*
- * Heiko Schocher, DENX Software Engineering, hs@denx.de.
- * based on:
- * FIPS-180-1 compliant SHA-1 implementation
- *
- * Copyright (C) 2003-2006 Christophe Devine
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License, version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-/*
- * The SHA-1 standard was published by NIST in 1993.
- *
- * http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
-
-#include <common.h>
-#include <digest.h>
-#include <init.h>
-#include <linux/string.h>
-#include <asm/byteorder.h>
-
-#include <crypto/internal.h>
-
-#define SHA1_SUM_POS -0x20
-#define SHA1_SUM_LEN 20
-
-typedef struct
-{
- uint32_t total[2]; /*!< number of bytes processed */
- uint32_t state[5]; /*!< intermediate digest state */
- uint8_t buffer[64]; /*!< data block being processed */
-}
-sha1_context;
-
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#define GET_UINT32_BE(n,b,i) (n) = be32_to_cpu(((uint32_t*)(b))[i / 4])
-#define PUT_UINT32_BE(n,b,i) ((uint32_t*)(b))[i / 4] = cpu_to_be32(n)
-
-/*
- * SHA-1 context setup
- */
-static void sha1_starts (sha1_context *ctx)
-{
- ctx->total[0] = 0;
- ctx->total[1] = 0;
-
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
-}
-
-static void sha1_process (sha1_context *ctx, uint8_t data[64])
-{
- uint32_t temp, W[16], A, B, C, D, E;
-
- GET_UINT32_BE (W[0], data, 0);
- GET_UINT32_BE (W[1], data, 4);
- GET_UINT32_BE (W[2], data, 8);
- GET_UINT32_BE (W[3], data, 12);
- GET_UINT32_BE (W[4], data, 16);
- GET_UINT32_BE (W[5], data, 20);
- GET_UINT32_BE (W[6], data, 24);
- GET_UINT32_BE (W[7], data, 28);
- GET_UINT32_BE (W[8], data, 32);
- GET_UINT32_BE (W[9], data, 36);
- GET_UINT32_BE (W[10], data, 40);
- GET_UINT32_BE (W[11], data, 44);
- GET_UINT32_BE (W[12], data, 48);
- GET_UINT32_BE (W[13], data, 52);
- GET_UINT32_BE (W[14], data, 56);
- GET_UINT32_BE (W[15], data, 60);
-
-#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#define R(t) ( \
- temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
- W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
- ( W[t & 0x0F] = S(temp,1) ) \
-)
-
-#define P(a,b,c,d,e,x) { \
- e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
-}
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
-
-#define F(x,y,z) (z ^ (x & (y ^ z)))
-#define K 0x5A827999
-
- P (A, B, C, D, E, W[0]);
- P (E, A, B, C, D, W[1]);
- P (D, E, A, B, C, W[2]);
- P (C, D, E, A, B, W[3]);
- P (B, C, D, E, A, W[4]);
- P (A, B, C, D, E, W[5]);
- P (E, A, B, C, D, W[6]);
- P (D, E, A, B, C, W[7]);
- P (C, D, E, A, B, W[8]);
- P (B, C, D, E, A, W[9]);
- P (A, B, C, D, E, W[10]);
- P (E, A, B, C, D, W[11]);
- P (D, E, A, B, C, W[12]);
- P (C, D, E, A, B, W[13]);
- P (B, C, D, E, A, W[14]);
- P (A, B, C, D, E, W[15]);
- P (E, A, B, C, D, R (16));
- P (D, E, A, B, C, R (17));
- P (C, D, E, A, B, R (18));
- P (B, C, D, E, A, R (19));
-
-#undef K
-#undef F
-
-#define F(x,y,z) (x ^ y ^ z)
-#define K 0x6ED9EBA1
-
- P (A, B, C, D, E, R (20));
- P (E, A, B, C, D, R (21));
- P (D, E, A, B, C, R (22));
- P (C, D, E, A, B, R (23));
- P (B, C, D, E, A, R (24));
- P (A, B, C, D, E, R (25));
- P (E, A, B, C, D, R (26));
- P (D, E, A, B, C, R (27));
- P (C, D, E, A, B, R (28));
- P (B, C, D, E, A, R (29));
- P (A, B, C, D, E, R (30));
- P (E, A, B, C, D, R (31));
- P (D, E, A, B, C, R (32));
- P (C, D, E, A, B, R (33));
- P (B, C, D, E, A, R (34));
- P (A, B, C, D, E, R (35));
- P (E, A, B, C, D, R (36));
- P (D, E, A, B, C, R (37));
- P (C, D, E, A, B, R (38));
- P (B, C, D, E, A, R (39));
-
-#undef K
-#undef F
-
-#define F(x,y,z) ((x & y) | (z & (x | y)))
-#define K 0x8F1BBCDC
-
- P (A, B, C, D, E, R (40));
- P (E, A, B, C, D, R (41));
- P (D, E, A, B, C, R (42));
- P (C, D, E, A, B, R (43));
- P (B, C, D, E, A, R (44));
- P (A, B, C, D, E, R (45));
- P (E, A, B, C, D, R (46));
- P (D, E, A, B, C, R (47));
- P (C, D, E, A, B, R (48));
- P (B, C, D, E, A, R (49));
- P (A, B, C, D, E, R (50));
- P (E, A, B, C, D, R (51));
- P (D, E, A, B, C, R (52));
- P (C, D, E, A, B, R (53));
- P (B, C, D, E, A, R (54));
- P (A, B, C, D, E, R (55));
- P (E, A, B, C, D, R (56));
- P (D, E, A, B, C, R (57));
- P (C, D, E, A, B, R (58));
- P (B, C, D, E, A, R (59));
-
-#undef K
-#undef F
-
-#define F(x,y,z) (x ^ y ^ z)
-#define K 0xCA62C1D6
-
- P (A, B, C, D, E, R (60));
- P (E, A, B, C, D, R (61));
- P (D, E, A, B, C, R (62));
- P (C, D, E, A, B, R (63));
- P (B, C, D, E, A, R (64));
- P (A, B, C, D, E, R (65));
- P (E, A, B, C, D, R (66));
- P (D, E, A, B, C, R (67));
- P (C, D, E, A, B, R (68));
- P (B, C, D, E, A, R (69));
- P (A, B, C, D, E, R (70));
- P (E, A, B, C, D, R (71));
- P (D, E, A, B, C, R (72));
- P (C, D, E, A, B, R (73));
- P (B, C, D, E, A, R (74));
- P (A, B, C, D, E, R (75));
- P (E, A, B, C, D, R (76));
- P (D, E, A, B, C, R (77));
- P (C, D, E, A, B, R (78));
- P (B, C, D, E, A, R (79));
-
-#undef K
-#undef F
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
-}
-
-/*
- * SHA-1 process buffer
- */
-static void sha1_update (sha1_context *ctx, uint8_t *input, uint32_t ilen)
-{
- uint32_t fill, left;
-
- if (ilen <= 0)
- return;
-
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
-
- ctx->total[0] += ilen;
- ctx->total[0] &= 0xFFFFFFFF;
-
- if (ctx->total[0] < ilen)
- ctx->total[1]++;
-
- if (left && ilen >= fill) {
- memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
- sha1_process (ctx, ctx->buffer);
- input += fill;
- ilen -= fill;
- left = 0;
- }
-
- while (ilen >= 64) {
- sha1_process (ctx, input);
- input += 64;
- ilen -= 64;
- }
-
- if (ilen > 0) {
- memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
- }
-}
-
-static uint8_t sha1_padding[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * SHA-1 final digest
- */
-static void sha1_finish (sha1_context *ctx, uint8_t output[20])
-{
- uint32_t last, padn;
- uint32_t high, low;
- uint8_t msglen[8];
-
- high = (ctx->total[0] >> 29)
- | (ctx->total[1] << 3);
- low = (ctx->total[0] << 3);
-
- PUT_UINT32_BE (high, msglen, 0);
- PUT_UINT32_BE (low, msglen, 4);
-
- last = ctx->total[0] & 0x3F;
- padn = (last < 56) ? (56 - last) : (120 - last);
-
- sha1_update (ctx, sha1_padding, padn);
- sha1_update (ctx, msglen, 8);
-
- PUT_UINT32_BE (ctx->state[0], output, 0);
- PUT_UINT32_BE (ctx->state[1], output, 4);
- PUT_UINT32_BE (ctx->state[2], output, 8);
- PUT_UINT32_BE (ctx->state[3], output, 12);
- PUT_UINT32_BE (ctx->state[4], output, 16);
-}
-
-static int digest_sha1_init(struct digest *d)
-{
- sha1_starts(d->ctx);
-
- return 0;
-}
-
-static int digest_sha1_update(struct digest *d, const void *data,
- unsigned long len)
-{
- sha1_update(d->ctx, (uint8_t*)data, len);
-
- return 0;
-}
-
-static int digest_sha1_final(struct digest *d, unsigned char *md)
-{
- sha1_finish(d->ctx, md);
-
- return 0;
-}
-
-static struct digest_algo m = {
- .base = {
- .name = "sha1",
- .driver_name = "sha1-generic",
- .priority = 0,
- },
-
- .init = digest_sha1_init,
- .update = digest_sha1_update,
- .final = digest_sha1_final,
- .digest = digest_generic_digest,
- .verify = digest_generic_verify,
- .length = SHA1_SUM_LEN,
- .ctx_length = sizeof(sha1_context),
-};
-
-static int sha1_digest_register(void)
-{
- int ret;
-
- ret = digest_algo_register(&m);
- if (ret)
- return ret;
-
- return digest_hmac_register(&m, 64);
-}
-device_initcall(sha1_digest_register);
+/*
+ * Cryptographic API.
+ *
+ * SHA1 Secure Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface.
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <common.h>
+#include <digest.h>
+#include <init.h>
+#include <linux/string.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+
+#include <crypto/sha.h>
+#include <crypto/internal.h>
+
+#define SHA_WORKSPACE_WORDS 16
+
+static int digest_sha1_init(struct digest *desc)
+{
+ struct sha1_state *ctx = digest_ctx(desc);
+
+ ctx->count = 0;
+
+ ctx->state[0] = SHA1_H0;
+ ctx->state[1] = SHA1_H1;
+ ctx->state[2] = SHA1_H2;
+ ctx->state[3] = SHA1_H3;
+ ctx->state[4] = SHA1_H4;
+
+ return 0;
+}
+
+/*
+ * If you have 32 registers or more, the compiler can (and should)
+ * try to change the array[] accesses into registers. However, on
+ * machines with less than ~25 registers, that won't really work,
+ * and at least gcc will make an unholy mess of it.
+ *
+ * So to avoid that mess which just slows things down, we force
+ * the stores to memory to actually happen (we might be better off
+ * with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as
+ * suggested by Artur Skawina - that will also make gcc unable to
+ * try to do the silly "optimize away loads" part because it won't
+ * see what the value will be).
+ *
+ * Ben Herrenschmidt reports that on PPC, the C version comes close
+ * to the optimized asm with this (ie on PPC you don't want that
+ * 'volatile', since there are lots of registers).
+ *
+ * On ARM we get the best code generation by forcing a full memory barrier
+ * between each SHA_ROUND, otherwise gcc happily get wild with spilling and
+ * the stack frame size simply explode and performance goes down the drain.
+ */
+
+#ifdef CONFIG_X86
+ #define setW(x, val) (*(volatile __u32 *)&W(x) = (val))
+#elif defined(CONFIG_ARM)
+ #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
+#else
+ #define setW(x, val) (W(x) = (val))
+#endif
+
+/* This "rolls" over the 512-bit array */
+#define W(x) (array[(x)&15])
+
+/*
+ * Where do we get the source from? The first 16 iterations get it from
+ * the input data, the next mix it from the 512-bit array.
+ */
+#define SHA_SRC(t) get_unaligned_be32((__u32 *)data + t)
+#define SHA_MIX(t) rol32(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
+
+#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
+ __u32 TEMP = input(t); setW(t, TEMP); \
+ E += TEMP + rol32(A,5) + (fn) + (constant); \
+ B = ror32(B, 2); } while (0)
+
+#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
+#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
+#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
+
+/**
+ * sha_transform - single block SHA1 transform
+ *
+ * @digest: 160 bit digest to update
+ * @data: 512 bits of data to hash
+ * @array: 16 words of workspace (see note)
+ *
+ * This function generates a SHA1 digest for a single 512-bit block.
+ * Be warned, it does not handle padding and message digest, do not
+ * confuse it with the full FIPS 180-1 digest algorithm for variable
+ * length messages.
+ *
+ * Note: If the hash is security sensitive, the caller should be sure
+ * to clear the workspace. This is left to the caller to avoid
+ * unnecessary clears between chained hashing operations.
+ */
+static void sha_transform(__u32 *digest, const char *data, __u32 *array)
+{
+ __u32 A, B, C, D, E;
+
+ A = digest[0];
+ B = digest[1];
+ C = digest[2];
+ D = digest[3];
+ E = digest[4];
+
+ /* Round 1 - iterations 0-16 take their input from 'data' */
+ T_0_15( 0, A, B, C, D, E);
+ T_0_15( 1, E, A, B, C, D);
+ T_0_15( 2, D, E, A, B, C);
+ T_0_15( 3, C, D, E, A, B);
+ T_0_15( 4, B, C, D, E, A);
+ T_0_15( 5, A, B, C, D, E);
+ T_0_15( 6, E, A, B, C, D);
+ T_0_15( 7, D, E, A, B, C);
+ T_0_15( 8, C, D, E, A, B);
+ T_0_15( 9, B, C, D, E, A);
+ T_0_15(10, A, B, C, D, E);
+ T_0_15(11, E, A, B, C, D);
+ T_0_15(12, D, E, A, B, C);
+ T_0_15(13, C, D, E, A, B);
+ T_0_15(14, B, C, D, E, A);
+ T_0_15(15, A, B, C, D, E);
+
+ /* Round 1 - tail. Input from 512-bit mixing array */
+ T_16_19(16, E, A, B, C, D);
+ T_16_19(17, D, E, A, B, C);
+ T_16_19(18, C, D, E, A, B);
+ T_16_19(19, B, C, D, E, A);
+
+ /* Round 2 */
+ T_20_39(20, A, B, C, D, E);
+ T_20_39(21, E, A, B, C, D);
+ T_20_39(22, D, E, A, B, C);
+ T_20_39(23, C, D, E, A, B);
+ T_20_39(24, B, C, D, E, A);
+ T_20_39(25, A, B, C, D, E);
+ T_20_39(26, E, A, B, C, D);
+ T_20_39(27, D, E, A, B, C);
+ T_20_39(28, C, D, E, A, B);
+ T_20_39(29, B, C, D, E, A);
+ T_20_39(30, A, B, C, D, E);
+ T_20_39(31, E, A, B, C, D);
+ T_20_39(32, D, E, A, B, C);
+ T_20_39(33, C, D, E, A, B);
+ T_20_39(34, B, C, D, E, A);
+ T_20_39(35, A, B, C, D, E);
+ T_20_39(36, E, A, B, C, D);
+ T_20_39(37, D, E, A, B, C);
+ T_20_39(38, C, D, E, A, B);
+ T_20_39(39, B, C, D, E, A);
+
+ /* Round 3 */
+ T_40_59(40, A, B, C, D, E);
+ T_40_59(41, E, A, B, C, D);
+ T_40_59(42, D, E, A, B, C);
+ T_40_59(43, C, D, E, A, B);
+ T_40_59(44, B, C, D, E, A);
+ T_40_59(45, A, B, C, D, E);
+ T_40_59(46, E, A, B, C, D);
+ T_40_59(47, D, E, A, B, C);
+ T_40_59(48, C, D, E, A, B);
+ T_40_59(49, B, C, D, E, A);
+ T_40_59(50, A, B, C, D, E);
+ T_40_59(51, E, A, B, C, D);
+ T_40_59(52, D, E, A, B, C);
+ T_40_59(53, C, D, E, A, B);
+ T_40_59(54, B, C, D, E, A);
+ T_40_59(55, A, B, C, D, E);
+ T_40_59(56, E, A, B, C, D);
+ T_40_59(57, D, E, A, B, C);
+ T_40_59(58, C, D, E, A, B);
+ T_40_59(59, B, C, D, E, A);
+
+ /* Round 4 */
+ T_60_79(60, A, B, C, D, E);
+ T_60_79(61, E, A, B, C, D);
+ T_60_79(62, D, E, A, B, C);
+ T_60_79(63, C, D, E, A, B);
+ T_60_79(64, B, C, D, E, A);
+ T_60_79(65, A, B, C, D, E);
+ T_60_79(66, E, A, B, C, D);
+ T_60_79(67, D, E, A, B, C);
+ T_60_79(68, C, D, E, A, B);
+ T_60_79(69, B, C, D, E, A);
+ T_60_79(70, A, B, C, D, E);
+ T_60_79(71, E, A, B, C, D);
+ T_60_79(72, D, E, A, B, C);
+ T_60_79(73, C, D, E, A, B);
+ T_60_79(74, B, C, D, E, A);
+ T_60_79(75, A, B, C, D, E);
+ T_60_79(76, E, A, B, C, D);
+ T_60_79(77, D, E, A, B, C);
+ T_60_79(78, C, D, E, A, B);
+ T_60_79(79, B, C, D, E, A);
+
+ digest[0] += A;
+ digest[1] += B;
+ digest[2] += C;
+ digest[3] += D;
+ digest[4] += E;
+}
+
+static int digest_sha1_update(struct digest *desc, const void *data,
+ unsigned long len)
+{
+ struct sha1_state *sctx = digest_ctx(desc);
+ unsigned int partial, done;
+ const u8 *src;
+
+ partial = sctx->count % SHA1_BLOCK_SIZE;
+ sctx->count += len;
+ done = 0;
+ src = data;
+
+ if ((partial + len) >= SHA1_BLOCK_SIZE) {
+ u32 temp[SHA_WORKSPACE_WORDS];
+
+ if (partial) {
+ done = -partial;
+ memcpy(sctx->buffer + partial, data,
+ done + SHA1_BLOCK_SIZE);
+ src = sctx->buffer;
+ }
+
+ do {
+ sha_transform(sctx->state, src, temp);
+ done += SHA1_BLOCK_SIZE;
+ src = data + done;
+ } while (done + SHA1_BLOCK_SIZE <= len);
+
+ memset(temp, 0, sizeof(temp));
+ partial = 0;
+ }
+ memcpy(sctx->buffer + partial, src, len - done);
+
+ return 0;
+}
+
+static int digest_sha1_final(struct digest *desc, unsigned char *md)
+{
+ struct sha1_state *sctx = digest_ctx(desc);
+ __be32 *dst = (__be32 *)md;
+ u32 i, index, padlen;
+ __be64 bits;
+ static const u8 padding[64] = { 0x80, };
+
+ bits = cpu_to_be64(sctx->count << 3);
+
+ /* Pad out to 56 mod 64 */
+ index = sctx->count & 0x3f;
+ padlen = (index < 56) ? (56 - index) : ((64+56) - index);
+ digest_sha1_update(desc, padding, padlen);
+
+ /* Append length */
+ digest_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
+
+ /* Store state in digest */
+ for (i = 0; i < 5; i++)
+ dst[i] = cpu_to_be32(sctx->state[i]);
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof *sctx);
+
+ return 0;
+}
+
+static struct digest_algo m = {
+ .base = {
+ .name = "sha1",
+ .driver_name = "sha1-generic",
+ .priority = 0,
+ },
+
+ .init = digest_sha1_init,
+ .update = digest_sha1_update,
+ .final = digest_sha1_final,
+ .digest = digest_generic_digest,
+ .verify = digest_generic_verify,
+ .length = SHA1_DIGEST_SIZE,
+ .ctx_length = sizeof(struct sha1_state),
+};
+
+static int sha1_digest_register(void)
+{
+ int ret;
+
+ ret = digest_algo_register(&m);
+ if (ret)
+ return ret;
+
+ return digest_hmac_register(&m, 64);
+}
+device_initcall(sha1_digest_register);
diff --git a/include/crypto/sha.h b/include/crypto/sha.h
new file mode 100644
index 0000000..190f8a0
--- /dev/null
+++ b/include/crypto/sha.h
@@ -0,0 +1,95 @@
+/*
+ * Common values for SHA algorithms
+ */
+
+#ifndef _CRYPTO_SHA_H
+#define _CRYPTO_SHA_H
+
+#include <linux/types.h>
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_BLOCK_SIZE 64
+
+#define SHA224_DIGEST_SIZE 28
+#define SHA224_BLOCK_SIZE 64
+
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_BLOCK_SIZE 64
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA384_BLOCK_SIZE 128
+
+#define SHA512_DIGEST_SIZE 64
+#define SHA512_BLOCK_SIZE 128
+
+#define SHA1_H0 0x67452301UL
+#define SHA1_H1 0xefcdab89UL
+#define SHA1_H2 0x98badcfeUL
+#define SHA1_H3 0x10325476UL
+#define SHA1_H4 0xc3d2e1f0UL
+
+#define SHA224_H0 0xc1059ed8UL
+#define SHA224_H1 0x367cd507UL
+#define SHA224_H2 0x3070dd17UL
+#define SHA224_H3 0xf70e5939UL
+#define SHA224_H4 0xffc00b31UL
+#define SHA224_H5 0x68581511UL
+#define SHA224_H6 0x64f98fa7UL
+#define SHA224_H7 0xbefa4fa4UL
+
+#define SHA256_H0 0x6a09e667UL
+#define SHA256_H1 0xbb67ae85UL
+#define SHA256_H2 0x3c6ef372UL
+#define SHA256_H3 0xa54ff53aUL
+#define SHA256_H4 0x510e527fUL
+#define SHA256_H5 0x9b05688cUL
+#define SHA256_H6 0x1f83d9abUL
+#define SHA256_H7 0x5be0cd19UL
+
+#define SHA384_H0 0xcbbb9d5dc1059ed8ULL
+#define SHA384_H1 0x629a292a367cd507ULL
+#define SHA384_H2 0x9159015a3070dd17ULL
+#define SHA384_H3 0x152fecd8f70e5939ULL
+#define SHA384_H4 0x67332667ffc00b31ULL
+#define SHA384_H5 0x8eb44a8768581511ULL
+#define SHA384_H6 0xdb0c2e0d64f98fa7ULL
+#define SHA384_H7 0x47b5481dbefa4fa4ULL
+
+#define SHA512_H0 0x6a09e667f3bcc908ULL
+#define SHA512_H1 0xbb67ae8584caa73bULL
+#define SHA512_H2 0x3c6ef372fe94f82bULL
+#define SHA512_H3 0xa54ff53a5f1d36f1ULL
+#define SHA512_H4 0x510e527fade682d1ULL
+#define SHA512_H5 0x9b05688c2b3e6c1fULL
+#define SHA512_H6 0x1f83d9abfb41bd6bULL
+#define SHA512_H7 0x5be0cd19137e2179ULL
+
+struct sha1_state {
+ u64 count;
+ u32 state[SHA1_DIGEST_SIZE / 4];
+ u8 buffer[SHA1_BLOCK_SIZE];
+};
+
+struct sha256_state {
+ u64 count;
+ u32 state[SHA256_DIGEST_SIZE / 4];
+ u8 buf[SHA256_BLOCK_SIZE];
+};
+
+struct sha512_state {
+ u64 count[2];
+ u64 state[SHA512_DIGEST_SIZE / 8];
+ u8 buf[SHA512_BLOCK_SIZE];
+};
+
+struct shash_desc;
+
+extern int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len);
+
+extern int crypto_sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len);
+
+extern int crypto_sha512_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len);
+#endif
diff --git a/include/digest.h b/include/digest.h
index c1221fc..e4b1696 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -126,4 +126,9 @@ static inline const char *digest_name(struct digest *d)
return d->algo->base.name;
}
+static inline void* digest_ctx(struct digest *d)
+{
+ return d->ctx;
+}
+
#endif /* __SH_ST_DEVICES_H__ */
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] arm: crypto: add sha1 assembly support
2015-03-24 9:19 ` [PATCH 1/4] command: digest: only set the key when specified Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 2/4] crypto: prepare to allow multiple digest driver Jean-Christophe PLAGNIOL-VILLARD
2015-03-24 9:19 ` [PATCH 3/4] crypto: sha1: switch to linux implementation Jean-Christophe PLAGNIOL-VILLARD
@ 2015-03-24 9:19 ` Jean-Christophe PLAGNIOL-VILLARD
2 siblings, 0 replies; 5+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2015-03-24 9:19 UTC (permalink / raw)
To: barebox
from Linux 3.9
linux generic implementation
$ ls -al build/versatilpb/arch/arm/pbl/zbarebox.bin
-rw-r--r-- 1 root root 210829 Mar 24 13:21 build/versatilpb/arch/arm/pbl/zbarebox.bin
linux arm v4 asm implementation
$ ls -al build/versatilpb/arch/arm/pbl/zbarebox.bin
-rw-r--r-- 1 root root 207786 Mar 24 13:23 build/versatilpb/arch/arm/pbl/zbarebox.bin
we win 3043 bytes and speed cf code
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/Makefile | 1 +
arch/arm/crypto/Makefile | 7 +
arch/arm/crypto/sha1-armv4-large.S | 497 +++++++++++++++++++++++++++++++++++++
arch/arm/crypto/sha1_glue.c | 137 ++++++++++
crypto/Kconfig | 8 +
5 files changed, 650 insertions(+)
create mode 100644 arch/arm/crypto/Makefile
create mode 100644 arch/arm/crypto/sha1-armv4-large.S
create mode 100644 arch/arm/crypto/sha1_glue.c
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 96c9f57..721aa9b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -269,6 +269,7 @@ endif
common-y += $(BOARD) arch/arm/boards/ $(MACH)
common-y += arch/arm/lib/ arch/arm/cpu/
+common-y += arch/arm/crypto/
common-$(CONFIG_OFTREE) += arch/arm/dts/
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
new file mode 100644
index 0000000..9a463b8
--- /dev/null
+++ b/arch/arm/crypto/Makefile
@@ -0,0 +1,7 @@
+#
+# Arch-specific CryptoAPI modules.
+#
+
+obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
+
+sha1-arm-y := sha1-armv4-large.o sha1_glue.o
diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S
new file mode 100644
index 0000000..99207c4
--- /dev/null
+++ b/arch/arm/crypto/sha1-armv4-large.S
@@ -0,0 +1,497 @@
+#define __ARM_ARCH__ __LINUX_ARM_ARCH__
+@ ====================================================================
+@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+
+@ sha1_block procedure for ARMv4.
+@
+@ January 2007.
+
+@ Size/performance trade-off
+@ ====================================================================
+@ impl size in bytes comp cycles[*] measured performance
+@ ====================================================================
+@ thumb 304 3212 4420
+@ armv4-small 392/+29% 1958/+64% 2250/+96%
+@ armv4-compact 740/+89% 1552/+26% 1840/+22%
+@ armv4-large 1420/+92% 1307/+19% 1370/+34%[***]
+@ full unroll ~5100/+260% ~1260/+4% ~1300/+5%
+@ ====================================================================
+@ thumb = same as 'small' but in Thumb instructions[**] and
+@ with recurring code in two private functions;
+@ small = detached Xload/update, loops are folded;
+@ compact = detached Xload/update, 5x unroll;
+@ large = interleaved Xload/update, 5x unroll;
+@ full unroll = interleaved Xload/update, full unroll, estimated[!];
+@
+@ [*] Manually counted instructions in "grand" loop body. Measured
+@ performance is affected by prologue and epilogue overhead,
+@ i-cache availability, branch penalties, etc.
+@ [**] While each Thumb instruction is twice smaller, they are not as
+@ diverse as ARM ones: e.g., there are only two arithmetic
+@ instructions with 3 arguments, no [fixed] rotate, addressing
+@ modes are limited. As result it takes more instructions to do
+@ the same job in Thumb, therefore the code is never twice as
+@ small and always slower.
+@ [***] which is also ~35% better than compiler generated code. Dual-
+@ issue Cortex A8 core was measured to process input block in
+@ ~990 cycles.
+
+@ August 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 13% improvement on
+@ Cortex A8 core and in absolute terms ~870 cycles per input block
+@ [or 13.6 cycles per byte].
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 10%
+@ improvement on Cortex A8 core and 12.2 cycles per byte.
+
+#include <linux/linkage.h>
+
+.text
+
+.align 2
+ENTRY(sha1_block_data_order)
+ stmdb sp!,{r4-r12,lr}
+ add r2,r1,r2,lsl#6 @ r2 to point at the end of r1
+ ldmia r0,{r3,r4,r5,r6,r7}
+.Lloop:
+ ldr r8,.LK_00_19
+ mov r14,sp
+ sub sp,sp,#15*4
+ mov r5,r5,ror#30
+ mov r6,r6,ror#30
+ mov r7,r7,ror#30 @ [6]
+.L_00_15:
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r4,r5 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ eor r10,r4,r5 @ F_xx_xx
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r3,r10,ror#2
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r3,r4 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ eor r10,r3,r4 @ F_xx_xx
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r7,r10,ror#2
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r7,r3 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ eor r10,r7,r3 @ F_xx_xx
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r6,r10,ror#2
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r6,r7 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ eor r10,r6,r7 @ F_xx_xx
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r5,r10,ror#2
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+ cmp r14,sp
+ bne .L_00_15 @ [((11+4)*5+2)*3]
+ sub sp,sp,#25*4
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+
+ ldr r8,.LK_20_39 @ [+15+16*4]
+ cmn sp,#0 @ [+3], clear carry to denote 20_39
+.L_20_39_or_60_79:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r4,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_20_39(B,C,D)
+ ARM( teq r14,sp ) @ preserve carry
+ THUMB( mov r11,sp )
+ THUMB( teq r14,r11 ) @ preserve carry
+ bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4]
+ bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes
+
+ ldr r8,.LK_40_59
+ sub sp,sp,#20*4 @ [+2]
+.L_40_59:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r4,r10,ror#2 @ F_xx_xx
+ and r11,r5,r6 @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_40_59(B,C,D)
+ add r7,r7,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ and r11,r4,r5 @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_40_59(B,C,D)
+ add r6,r6,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ and r11,r3,r4 @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_40_59(B,C,D)
+ add r5,r5,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ and r11,r7,r3 @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_40_59(B,C,D)
+ add r4,r4,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ and r11,r6,r7 @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_40_59(B,C,D)
+ add r3,r3,r11,ror#2
+ cmp r14,sp
+ bne .L_40_59 @ [+((12+5)*5+2)*4]
+
+ ldr r8,.LK_60_79
+ sub sp,sp,#20*4
+ cmp sp,#0 @ set carry to denote 60_79
+ b .L_20_39_or_60_79 @ [+4], spare 300 bytes
+.L_done:
+ add sp,sp,#80*4 @ "deallocate" stack frame
+ ldmia r0,{r8,r9,r10,r11,r12}
+ add r3,r8,r3
+ add r4,r9,r4
+ add r5,r10,r5,ror#2
+ add r6,r11,r6,ror#2
+ add r7,r12,r7,ror#2
+ stmia r0,{r3,r4,r5,r6,r7}
+ teq r1,r2
+ bne .Lloop @ [+18], total 1307
+
+ ldmia sp!,{r4-r12,pc}
+.align 2
+.LK_00_19: .word 0x5a827999
+.LK_20_39: .word 0x6ed9eba1
+.LK_40_59: .word 0x8f1bbcdc
+.LK_60_79: .word 0xca62c1d6
+ENDPROC(sha1_block_data_order)
+.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/arch/arm/crypto/sha1_glue.c b/arch/arm/crypto/sha1_glue.c
new file mode 100644
index 0000000..133f60a
--- /dev/null
+++ b/arch/arm/crypto/sha1_glue.c
@@ -0,0 +1,137 @@
+/*
+ * Cryptographic API.
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation
+ *
+ * This file is based on sha1_generic.c and sha1_ssse3_glue.c
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) Mathias Krause <minipli@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <common.h>
+#include <digest.h>
+#include <init.h>
+#include <crypto/sha.h>
+#include <crypto/internal.h>
+#include <asm/byteorder.h>
+
+void sha1_block_data_order(u32 *digest,
+ const unsigned char *data, unsigned int rounds);
+
+
+static int sha1_init(struct digest *desc)
+{
+ struct sha1_state *sctx = digest_ctx(desc);
+
+ *sctx = (struct sha1_state){
+ .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+ };
+
+ return 0;
+}
+
+
+static int __sha1_update(struct sha1_state *sctx, const u8 *data,
+ unsigned int len, unsigned int partial)
+{
+ unsigned int done = 0;
+
+ sctx->count += len;
+
+ if (partial) {
+ done = SHA1_BLOCK_SIZE - partial;
+ memcpy(sctx->buffer + partial, data, done);
+ sha1_block_data_order(sctx->state, sctx->buffer, 1);
+ }
+
+ if (len - done >= SHA1_BLOCK_SIZE) {
+ const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
+ sha1_block_data_order(sctx->state, data + done, rounds);
+ done += rounds * SHA1_BLOCK_SIZE;
+ }
+
+ memcpy(sctx->buffer, data + done, len - done);
+ return 0;
+}
+
+
+int sha1_update_arm(struct digest *desc, const void *data,
+ unsigned long len)
+{
+ struct sha1_state *sctx = digest_ctx(desc);
+ unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+ int res;
+
+ /* Handle the fast case right here */
+ if (partial + len < SHA1_BLOCK_SIZE) {
+ sctx->count += len;
+ memcpy(sctx->buffer + partial, data, len);
+ return 0;
+ }
+ res = __sha1_update(sctx, data, len, partial);
+ return res;
+}
+EXPORT_SYMBOL_GPL(sha1_update_arm);
+
+
+/* Add padding and return the message digest. */
+static int sha1_final(struct digest *desc, u8 *out)
+{
+ struct sha1_state *sctx = digest_ctx(desc);
+ unsigned int i, index, padlen;
+ __be32 *dst = (__be32 *)out;
+ __be64 bits;
+ static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
+
+ bits = cpu_to_be64(sctx->count << 3);
+
+ /* Pad out to 56 mod 64 and append length */
+ index = sctx->count % SHA1_BLOCK_SIZE;
+ padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
+ /* We need to fill a whole block for __sha1_update() */
+ if (padlen <= 56) {
+ sctx->count += padlen;
+ memcpy(sctx->buffer + index, padding, padlen);
+ } else {
+ __sha1_update(sctx, padding, padlen, index);
+ }
+ __sha1_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
+
+ /* Store state in digest */
+ for (i = 0; i < 5; i++)
+ dst[i] = cpu_to_be32(sctx->state[i]);
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof(*sctx));
+ return 0;
+}
+
+static struct digest_algo m = {
+ .base = {
+ .name = "sha1",
+ .driver_name = "sha1-asm",
+ .priority = 150,
+ },
+
+ .init = sha1_init,
+ .update = sha1_update_arm,
+ .final = sha1_final,
+ .digest = digest_generic_digest,
+ .verify = digest_generic_verify,
+ .length = SHA1_DIGEST_SIZE,
+ .ctx_length = sizeof(struct sha1_state),
+};
+
+static int sha1_mod_init(void)
+{
+ return digest_algo_register(&m);
+}
+device_initcall(sha1_mod_init);
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 5a69236..1816dbd 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -61,6 +61,14 @@ config DIGEST_HMAC_GENERIC
bool "HMAC"
select DIGEST_HMAC
+config DIGEST_SHA1_ARM
+ tristate "SHA1 digest algorithm (ARM-asm)"
+ depends on ARM
+ select SHA1
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+ using optimized ARM assembler.
+
endif
config CRYPTO_PBKDF2
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread