Browse Source

Linux_SDK_V0.9.5

thead_admin 1 year ago
commit
1f563c5db5
100 changed files with 21300 additions and 0 deletions
  1. 24 0
      ISO7816/Makefile
  2. 79 0
      ISO7816/dsmart_card_interface.h
  3. 107 0
      ISO7816/ioctl.h
  4. BIN
      ISO7816/iso7816
  5. 124 0
      ISO7816/iso7816_test.c
  6. 98 0
      ISO7816/tags
  7. 2 0
      README.txt
  8. 30 0
      efuse-hal-lib/Makefile
  9. 1 0
      efuse-hal-lib/README.txt
  10. 22 0
      efuse-hal-lib/lib/src/Makefile
  11. 377 0
      efuse-hal-lib/lib/src/efuse-api.h
  12. 1507 0
      efuse-hal-lib/lib/src/light-efuse-hal.c
  13. BIN
      efuse-hal-lib/lib/src/light-efuse-hal.o
  14. 22 0
      efuse-hal-lib/test/efuse_demo/Makefile
  15. 377 0
      efuse-hal-lib/test/efuse_demo/efuse-api.h
  16. 470 0
      efuse-hal-lib/test/efuse_demo/light-efuse-test.c
  17. BIN
      efuse-hal-lib/test/efuse_demo/light-efuse-test.o
  18. BIN
      efuse-hal-lib/test/output/efuse_demo
  19. 548 0
      emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/hmac_sha2.c
  20. 144 0
      emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/hmac_sha2.h
  21. 953 0
      emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/sha2.c
  22. 112 0
      emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/sha2.h
  23. 12 0
      emmc_hal_lib/mmc-utils/Android.mk
  24. 59 0
      emmc_hal_lib/mmc-utils/Makefile
  25. 293 0
      emmc_hal_lib/mmc-utils/csi_rpmb.c
  26. 62 0
      emmc_hal_lib/mmc-utils/csi_rpmb.h
  27. 108 0
      emmc_hal_lib/mmc-utils/csi_test.c
  28. 2431 0
      emmc_hal_lib/mmc-utils/lsmmc.c
  29. 5 0
      emmc_hal_lib/mmc-utils/man/Makefile
  30. 125 0
      emmc_hal_lib/mmc-utils/man/mmc.1
  31. 73 0
      emmc_hal_lib/mmc-utils/mmc.c
  32. 199 0
      emmc_hal_lib/mmc-utils/mmc.h
  33. 2659 0
      emmc_hal_lib/mmc-utils/mmc_cmds.c
  34. 47 0
      emmc_hal_lib/mmc-utils/mmc_cmds.h
  35. BIN
      emmc_hal_lib/mmc-utils/rpmb_test.png
  36. 22 0
      iopmp_hal_lib/Makefile
  37. 126 0
      iopmp_hal_lib/light-iopmp-hal.c
  38. 59 0
      iopmp_hal_lib/light-iopmp.h
  39. BIN
      iopmp_hal_lib/output/libiopmp.so
  40. 57 0
      iopmp_hal_lib/output/light-iopmp.h
  41. BIN
      light_fm_aon/light_aon_fpga.bin
  42. BIN
      light_fm_aon/light_aon_fpga.elf
  43. 1 0
      rambus_sec_lib/bin/EIP120_scripts/aad.txt
  44. 186 0
      rambus_sec_lib/bin/EIP120_scripts/ciphertest.sh
  45. 1 0
      rambus_sec_lib/bin/EIP120_scripts/ckey.txt
  46. 1 0
      rambus_sec_lib/bin/EIP120_scripts/hkey.txt
  47. 219 0
      rambus_sec_lib/bin/EIP120_scripts/htest.sh
  48. 1 0
      rambus_sec_lib/bin/EIP120_scripts/iv.txt
  49. 1 0
      rambus_sec_lib/bin/EIP120_scripts/key.txt
  50. 0 0
      rambus_sec_lib/bin/EIP120_scripts/lorum.txt
  51. 0 0
      rambus_sec_lib/bin/EIP120_scripts/message.txt
  52. 0 0
      rambus_sec_lib/bin/EIP120_scripts/tag.txt
  53. 0 0
      rambus_sec_lib/bin/EIP120_scripts/testdatain.txt
  54. 344 0
      rambus_sec_lib/bin/EIP28_scripts/dh-key-agreement.sh
  55. 342 0
      rambus_sec_lib/bin/EIP28_scripts/ecdh-key-agreement.sh
  56. 380 0
      rambus_sec_lib/bin/EIP28_scripts/edcsa-sign-and-verify.sh
  57. 415 0
      rambus_sec_lib/bin/EIP28_scripts/rsa-encrypt-decrypt-sign-verify.sh
  58. 376 0
      rambus_sec_lib/bin/EIP28_scripts/sm2-encrypt-and-decrypt.sh
  59. 368 0
      rambus_sec_lib/bin/EIP28_scripts/sm2-sign-and-verify.sh
  60. 37 0
      rambus_sec_lib/bin/EIP28_scripts/test-all.sh
  61. 318 0
      rambus_sec_lib/bin/EIP28_scripts/x25519-key-agreement.sh
  62. 51 0
      rambus_sec_lib/bin/Makefile
  63. 232 0
      rambus_sec_lib/bin/c_rehash
  64. BIN
      rambus_sec_lib/bin/cipher
  65. BIN
      rambus_sec_lib/bin/digest
  66. BIN
      rambus_sec_lib/bin/openssl
  67. BIN
      rambus_sec_lib/bin/sm2decrypt
  68. BIN
      rambus_sec_lib/bin/sm2encrypt
  69. BIN
      rambus_sec_lib/bin/sm2sign
  70. BIN
      rambus_sec_lib/bin/sm2verify
  71. 92 0
      rambus_sec_lib/include/openssl/aes.h
  72. 886 0
      rambus_sec_lib/include/openssl/asn1.h
  73. 10 0
      rambus_sec_lib/include/openssl/asn1_mac.h
  74. 256 0
      rambus_sec_lib/include/openssl/asn1err.h
  75. 945 0
      rambus_sec_lib/include/openssl/asn1t.h
  76. 76 0
      rambus_sec_lib/include/openssl/async.h
  77. 42 0
      rambus_sec_lib/include/openssl/asyncerr.h
  78. 801 0
      rambus_sec_lib/include/openssl/bio.h
  79. 124 0
      rambus_sec_lib/include/openssl/bioerr.h
  80. 61 0
      rambus_sec_lib/include/openssl/blowfish.h
  81. 539 0
      rambus_sec_lib/include/openssl/bn.h
  82. 100 0
      rambus_sec_lib/include/openssl/bnerr.h
  83. 58 0
      rambus_sec_lib/include/openssl/buffer.h
  84. 34 0
      rambus_sec_lib/include/openssl/buffererr.h
  85. 83 0
      rambus_sec_lib/include/openssl/camellia.h
  86. 53 0
      rambus_sec_lib/include/openssl/cast.h
  87. 41 0
      rambus_sec_lib/include/openssl/cmac.h
  88. 339 0
      rambus_sec_lib/include/openssl/cms.h
  89. 202 0
      rambus_sec_lib/include/openssl/cmserr.h
  90. 53 0
      rambus_sec_lib/include/openssl/comp.h
  91. 44 0
      rambus_sec_lib/include/openssl/comperr.h
  92. 168 0
      rambus_sec_lib/include/openssl/conf.h
  93. 40 0
      rambus_sec_lib/include/openssl/conf_api.h
  94. 76 0
      rambus_sec_lib/include/openssl/conferr.h
  95. 445 0
      rambus_sec_lib/include/openssl/crypto.h
  96. 57 0
      rambus_sec_lib/include/openssl/cryptoerr.h
  97. 474 0
      rambus_sec_lib/include/openssl/ct.h
  98. 80 0
      rambus_sec_lib/include/openssl/cterr.h
  99. 174 0
      rambus_sec_lib/include/openssl/des.h
  100. 340 0
      rambus_sec_lib/include/openssl/dh.h

+ 24 - 0
ISO7816/Makefile

@@ -0,0 +1,24 @@
+##
+ # Copyright (C) 2021 Alibaba Group Holding Limited
+##
+
+CC=$(CROSS_COMPILE)gcc
+SOURCE:=$(wildcard *.c)
+OBJS:=$(patsubst %.c,%.o,$(SOURCE))
+OUTDIR=./output
+TARGET_ELF:=iso7816
+
+
+all:$(OBJS)
+	echo $(OBJS)
+	mkdir -p $(OUTDIR)
+	$(CC) -o $(OUTDIR)/$(TARGET_ELF) $(OBJS)
+
+%.o:%.c
+	@echo Compiling $< ...
+	$(CC) -c $< -o $*.o
+
+.PHONY: clean
+
+clean:
+	rm -rf $(OUTDIR)/$(TARGET_ELF) *.o

+ 79 - 0
ISO7816/dsmart_card_interface.h

@@ -0,0 +1,79 @@
+#ifndef _DSMART_CARD_INTERFACE_H
+#define _DSMART_CARD_INTERFACE_H
+
+#define DSMART_CARD_OK			0
+#define DSMART_CARD_E_ACCESS		1
+#define DSMART_CARD_E_DATA_TIMEOUT	2
+#define DSMART_CARD_E_NOCARD		3
+#define DSMART_CARD_E_NOACT		4
+#define DSMART_CARD_E_REMOVED		5
+#define DSMART_CARD_E_NO_RX_EV		6
+#define DSMART_CARD_E_NO_TX_EV		7
+#define DSMART_CARD_E_NO_CRD_EV		8
+#define DSMART_CARD_E_ACT_TIMEOUT	9
+#define DSMART_CARD_E_DATA_RCV_FAILED	10
+#define DSMART_CARD_E_ACTIVATE_FAILED	11
+#define DSMART_CARD_E_TX_FULL		12
+#define DSMART_CARD_E_PAR_ERR		13
+#define DSMART_CARD_E_CRC_ERR		14
+#define DSMART_CARD_E_REP_ERR		15
+#define DSMART_CARD_E_CWT_TIM		16
+#define DSMART_CARD_E_RX_OVER		17
+#define DSMART_CARD_STATE_ERR_EVENT	18
+
+#define CARD_PROTOCOL_T0	1
+#define	CARD_PROTOCOL_T1	2
+
+struct dsmart_card_atr {
+	unsigned char atr_buffer[64];
+	unsigned int len;	/* length of ATR received */
+	int errval;
+};
+
+struct dsmart_card_rcv {
+	unsigned char rcv_buffer[256];
+	int rcv_length;
+	int time_out;
+	int errval;
+};
+
+struct dsmart_card_xmt {
+	unsigned char xmt_buffer[256];
+	int xmt_length;
+	int time_out;
+	int errval;
+};
+
+struct dsmart_card_timing {
+	unsigned int wwt;
+	unsigned int cwt;
+	unsigned int bwt;
+	unsigned int bgt;
+	unsigned int egt;
+};
+
+struct dsmart_card_baud {
+	unsigned char di;
+	unsigned char fi;
+};
+
+enum dsmart_protocol_type {
+	DSMART_CARD_PROTOCOL_T0 = 0,
+	DSMART_CARD_PROTOCOL_T1 = 1,
+};
+
+/* ioctl encodings */
+#define DSMART_CARD_BASE			0xc0
+#define DSMART_CARD_IOCTL_SET_PROTOCOL		_IOR(DSMART_CARD_BASE, 1, int)
+#define DSMART_CARD_IOCTL_DEACTIVATE		_IOR(DSMART_CARD_BASE, 2, int)
+#define DSMART_CARD_IOCTL_COLD_RESET		_IOR(DSMART_CARD_BASE, 3, int)
+#define DSMART_CARD_IOCTL_WARM_RESET		_IOR(DSMART_CARD_BASE, 4, int)
+#define DSMART_CARD_IOCTL_SET_TIMING		_IOR(DSMART_CARD_BASE, 5, int)
+#define DSMART_CARD_IOCTL_SET_BAUD		_IOR(DSMART_CARD_BASE, 6, int)
+#define DSMART_CARD_IOCTL_SET_RX_THRESHOLD	_IOR(DSMART_CARD_BASE, 7, int)
+#define DSMART_CARD_IOCTL_SET_TX_THRESHOLD	_IOR(DSMART_CARD_BASE, 8, int)
+#define DSMART_CARD_IOCTL_XMT			_IOR(DSMART_CARD_BASE, 9, int)
+#define DSMART_CARD_IOCTL_RCV			_IOR(DSMART_CARD_BASE, 10, int)
+#define DSMART_CARD_IOCTL_ATR_RCV		_IOR(DSMART_CARD_BASE, 11, int)
+
+#endif

+ 107 - 0
ISO7816/ioctl.h

@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_GENERIC_IOCTL_H
+#define _UAPI_ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The generic ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+
+/*
+ * Let any architecture override either of the following before
+ * including this file.
+ */
+
+#ifndef _IOC_SIZEBITS
+# define _IOC_SIZEBITS	14
+#endif
+
+#ifndef _IOC_DIRBITS
+# define _IOC_DIRBITS	2
+#endif
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits, which any architecture can choose to override
+ * before including this file.
+ *
+ * NOTE: _IOC_WRITE means userland is writing and kernel is
+ * reading. _IOC_READ means userland is reading and kernel is writing.
+ */
+
+#ifndef _IOC_NONE
+# define _IOC_NONE	0U
+#endif
+
+#ifndef _IOC_WRITE
+# define _IOC_WRITE	1U
+#endif
+
+#ifndef _IOC_READ
+# define _IOC_READ	2U
+#endif
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+#ifndef __KERNEL__
+#define _IOC_TYPECHECK(t) (sizeof(t))
+#endif
+
+/*
+ * Used to create numbers.
+ *
+ * NOTE: _IOW means userland is writing and kernel is reading. _IOR
+ * means userland is reading and kernel is writing.
+ */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _UAPI_ASM_GENERIC_IOCTL_H */

BIN
ISO7816/iso7816


+ 124 - 0
ISO7816/iso7816_test.c

@@ -0,0 +1,124 @@
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include "dsmart_card_interface.h"
+#include "ioctl.h"
+
+int main()
+{
+	int ret, i;
+	struct dsmart_card_baud baud_data;
+	unsigned int protocol = DSMART_CARD_PROTOCOL_T0;
+	struct dsmart_card_atr  atr = { 0 };
+	struct dsmart_card_rcv rcv_data = {};
+	struct dsmart_card_xmt xmt_data = {};
+	struct dsmart_card_timing timing_data;
+
+	int fd = open("/dev/dsmart_card", O_RDWR);
+	if (fd < 0) {
+		perror("failed to open iso7816 smart card\n");
+		exit(1);
+	}
+
+	printf("dsmart card cmd = 0x%x\n", DSMART_CARD_IOCTL_COLD_RESET);
+	ret = ioctl(fd, DSMART_CARD_IOCTL_COLD_RESET, &atr);
+	if (ret < 0) {
+		printf("failed to get atr from slave card(%d)\n", ret);
+		exit(1);
+	}
+
+	ret = ioctl(fd, DSMART_CARD_IOCTL_ATR_RCV, (unsigned long)&atr);
+	if (ret < 0) {
+		printf("failed to get atr data from slave card(%d)\n", ret);
+		exit(1);
+	}
+
+	printf("\nATR data length: %d, result: %d, ATR DATA:\n", atr.len, atr.errval);
+
+	for (i = 0; i < atr.len; i++)
+		printf("0x%02x ", atr.atr_buffer[i]);
+
+	printf("\n\nset transmision protocol T0\n");
+	ret = ioctl(fd, DSMART_CARD_IOCTL_SET_PROTOCOL, &protocol);
+	if (ret < 0) {
+		printf("failed to set transmision protocol(%d)\n", ret);
+		exit(1);
+	}
+
+	baud_data.di = 1;
+	baud_data.fi = 1;
+
+	printf("\nset baud rate, fi: %d, di: %d\n", baud_data.fi, baud_data.di);
+	ret = ioctl(fd, DSMART_CARD_IOCTL_SET_BAUD, &baud_data);
+	if (ret < 0) {
+		printf("failed to set baud rate(%d)\n", ret);
+		exit(1);
+	}
+
+
+	timing_data.wwt = 9600;
+	timing_data.bgt = 0;
+	timing_data.cwt = 0;
+	timing_data.bwt = 0;
+	timing_data.egt = 0;
+
+	printf("\nset timming window, wwt: %d, bgt: %d, cwt: %d, bwt: %d, egt: %d\n", timing_data.wwt, timing_data.bgt, timing_data.cwt, timing_data.bwt, timing_data.egt);
+	ret = ioctl(fd, DSMART_CARD_IOCTL_SET_TIMING, &timing_data);
+	if (ret < 0) {
+		printf("failed to set timing window(%d)\n", ret);
+		exit(1);
+	}
+
+	printf("\nget data from sim card ");
+	ret = ioctl(fd, DSMART_CARD_IOCTL_RCV, &rcv_data);
+	if (ret < 0) {
+		printf("failed to receive data from sim card\n");
+		exit(1);
+	}
+
+	printf(", len: %d\n", rcv_data.rcv_length);
+	for (i = 0; i < rcv_data.rcv_length; i++) {
+		if (i % 8 == 0)
+			printf("\n");
+		printf("0x%x  ", rcv_data.rcv_buffer[i]);
+	}
+
+
+	printf("\nreset the smart card\n");
+	ret = ioctl(fd, DSMART_CARD_IOCTL_WARM_RESET, NULL);
+	if (ret < 0) {
+		printf("failed to reset the smart card(%d)\n", ret);
+		exit(1);
+	}
+
+
+	ret = ioctl(fd, DSMART_CARD_IOCTL_ATR_RCV, (unsigned long)&atr);
+	if (ret < 0) {
+		printf("failed to get atr data from slave card(%d)\n", ret);
+		exit(1);
+	}
+
+	printf("\n\nATR data length after warm reset: %d, result: %d, ATR DATA:\n", atr.len, atr.errval);
+	for (i = 0; i < atr.len; i++)
+		printf("0x%02x ", atr.atr_buffer[i]);
+
+	printf("\n\nterminate the session\n");
+	ret = ioctl(fd, DSMART_CARD_IOCTL_DEACTIVATE, NULL);
+	if (ret < 0) {
+		printf("failed to terminate the session\n");
+		exit(1);
+	}
+
+	printf("\nsucceed to access smart card\n");
+
+	close(fd);
+
+	return 0;
+}

+ 98 - 0
ISO7816/tags

@@ -0,0 +1,98 @@
+!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME	Exuberant Ctags	//
+!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
+!_TAG_PROGRAM_VERSION	5.9~svn20110310	//
+CARD_PROTOCOL_T0	dsmart_card_interface.h	24;"	d
+CARD_PROTOCOL_T1	dsmart_card_interface.h	25;"	d
+DSMART_CARD_BASE	dsmart_card_interface.h	61;"	d
+DSMART_CARD_E_ACCESS	dsmart_card_interface.h	5;"	d
+DSMART_CARD_E_ACTIVATE_FAILED	dsmart_card_interface.h	15;"	d
+DSMART_CARD_E_ACT_TIMEOUT	dsmart_card_interface.h	13;"	d
+DSMART_CARD_E_CRC_ERR	dsmart_card_interface.h	18;"	d
+DSMART_CARD_E_CWT_TIM	dsmart_card_interface.h	20;"	d
+DSMART_CARD_E_DATA_RCV_FAILED	dsmart_card_interface.h	14;"	d
+DSMART_CARD_E_DATA_TIMEOUT	dsmart_card_interface.h	6;"	d
+DSMART_CARD_E_NOACT	dsmart_card_interface.h	8;"	d
+DSMART_CARD_E_NOCARD	dsmart_card_interface.h	7;"	d
+DSMART_CARD_E_NO_CRD_EV	dsmart_card_interface.h	12;"	d
+DSMART_CARD_E_NO_RX_EV	dsmart_card_interface.h	10;"	d
+DSMART_CARD_E_NO_TX_EV	dsmart_card_interface.h	11;"	d
+DSMART_CARD_E_PAR_ERR	dsmart_card_interface.h	17;"	d
+DSMART_CARD_E_REMOVED	dsmart_card_interface.h	9;"	d
+DSMART_CARD_E_REP_ERR	dsmart_card_interface.h	19;"	d
+DSMART_CARD_E_RX_OVER	dsmart_card_interface.h	21;"	d
+DSMART_CARD_E_TX_FULL	dsmart_card_interface.h	16;"	d
+DSMART_CARD_IOCTL_ATR_RCV	dsmart_card_interface.h	72;"	d
+DSMART_CARD_IOCTL_COLD_RESET	dsmart_card_interface.h	64;"	d
+DSMART_CARD_IOCTL_DEACTIVATE	dsmart_card_interface.h	63;"	d
+DSMART_CARD_IOCTL_RCV	dsmart_card_interface.h	71;"	d
+DSMART_CARD_IOCTL_SET_BAUD	dsmart_card_interface.h	67;"	d
+DSMART_CARD_IOCTL_SET_PROTOCOL	dsmart_card_interface.h	62;"	d
+DSMART_CARD_IOCTL_SET_RX_THRESHOLD	dsmart_card_interface.h	68;"	d
+DSMART_CARD_IOCTL_SET_TIMING	dsmart_card_interface.h	66;"	d
+DSMART_CARD_IOCTL_SET_TX_THRESHOLD	dsmart_card_interface.h	69;"	d
+DSMART_CARD_IOCTL_WARM_RESET	dsmart_card_interface.h	65;"	d
+DSMART_CARD_IOCTL_XMT	dsmart_card_interface.h	70;"	d
+DSMART_CARD_OK	dsmart_card_interface.h	4;"	d
+DSMART_CARD_STATE_ERR_EVENT	dsmart_card_interface.h	22;"	d
+IOCSIZE_MASK	ioctl.h	104;"	d
+IOCSIZE_SHIFT	ioctl.h	105;"	d
+IOC_IN	ioctl.h	101;"	d
+IOC_INOUT	ioctl.h	103;"	d
+IOC_OUT	ioctl.h	102;"	d
+_DSMART_CARD_INTERFACE_H	dsmart_card_interface.h	2;"	d
+_IO	ioctl.h	85;"	d
+_IOC	ioctl.h	69;"	d
+_IOC_DIR	ioctl.h	94;"	d
+_IOC_DIRBITS	ioctl.h	36;"	d
+_IOC_DIRMASK	ioctl.h	42;"	d
+_IOC_DIRSHIFT	ioctl.h	47;"	d
+_IOC_NONE	ioctl.h	58;"	d
+_IOC_NR	ioctl.h	96;"	d
+_IOC_NRBITS	ioctl.h	23;"	d
+_IOC_NRMASK	ioctl.h	39;"	d
+_IOC_NRSHIFT	ioctl.h	44;"	d
+_IOC_READ	ioctl.h	66;"	d
+_IOC_SIZE	ioctl.h	97;"	d
+_IOC_SIZEBITS	ioctl.h	32;"	d
+_IOC_SIZEMASK	ioctl.h	41;"	d
+_IOC_SIZESHIFT	ioctl.h	46;"	d
+_IOC_TYPE	ioctl.h	95;"	d
+_IOC_TYPEBITS	ioctl.h	24;"	d
+_IOC_TYPECHECK	ioctl.h	76;"	d
+_IOC_TYPEMASK	ioctl.h	40;"	d
+_IOC_TYPESHIFT	ioctl.h	45;"	d
+_IOC_WRITE	ioctl.h	62;"	d
+_IOR	ioctl.h	86;"	d
+_IOR_BAD	ioctl.h	89;"	d
+_IOW	ioctl.h	87;"	d
+_IOWR	ioctl.h	88;"	d
+_IOWR_BAD	ioctl.h	91;"	d
+_IOW_BAD	ioctl.h	90;"	d
+_UAPI_ASM_GENERIC_IOCTL_H	ioctl.h	3;"	d
+atr_buffer	dsmart_card_interface.h	/^	unsigned char *atr_buffer;$/;"	m	struct:dsmart_card_atr
+bgt	dsmart_card_interface.h	/^	unsigned int bgt;$/;"	m	struct:dsmart_card_timing
+bwt	dsmart_card_interface.h	/^	unsigned int bwt;$/;"	m	struct:dsmart_card_timing
+cwt	dsmart_card_interface.h	/^	unsigned int cwt;$/;"	m	struct:dsmart_card_timing
+di	dsmart_card_interface.h	/^	unsigned char di;$/;"	m	struct:dsmart_card_baud
+dsmart_card_atr	dsmart_card_interface.h	/^struct dsmart_card_atr {$/;"	s
+dsmart_card_baud	dsmart_card_interface.h	/^struct dsmart_card_baud {$/;"	s
+dsmart_card_rcv	dsmart_card_interface.h	/^struct dsmart_card_rcv {$/;"	s
+dsmart_card_timing	dsmart_card_interface.h	/^struct dsmart_card_timing {$/;"	s
+dsmart_card_xmt	dsmart_card_interface.h	/^struct dsmart_card_xmt {$/;"	s
+egt	dsmart_card_interface.h	/^	unsigned int egt;$/;"	m	struct:dsmart_card_timing
+errval	dsmart_card_interface.h	/^	int errval;$/;"	m	struct:dsmart_card_atr
+errval	dsmart_card_interface.h	/^	int errval;$/;"	m	struct:dsmart_card_rcv
+errval	dsmart_card_interface.h	/^	int errval;$/;"	m	struct:dsmart_card_xmt
+fi	dsmart_card_interface.h	/^	unsigned char fi;$/;"	m	struct:dsmart_card_baud
+len	dsmart_card_interface.h	/^	unsigned int len;	\/* length of ATR received *\/$/;"	m	struct:dsmart_card_atr
+main	iso7816_test.c	/^int main()$/;"	f
+rcv_buffer	dsmart_card_interface.h	/^	unsigned char *rcv_buffer;$/;"	m	struct:dsmart_card_rcv
+rcv_length	dsmart_card_interface.h	/^	int rcv_length;$/;"	m	struct:dsmart_card_rcv
+time_out	dsmart_card_interface.h	/^	int time_out;$/;"	m	struct:dsmart_card_rcv
+time_out	dsmart_card_interface.h	/^	int time_out;$/;"	m	struct:dsmart_card_xmt
+wwt	dsmart_card_interface.h	/^	unsigned int wwt;$/;"	m	struct:dsmart_card_timing
+xmt_buffer	dsmart_card_interface.h	/^	unsigned char *xmt_buffer;$/;"	m	struct:dsmart_card_xmt
+xmt_length	dsmart_card_interface.h	/^	int xmt_length;$/;"	m	struct:dsmart_card_xmt

+ 2 - 0
README.txt

@@ -0,0 +1,2 @@
+1: This repo is to store various librarys source code;
+2: Please mkdir a new directory when you need add a new library, such as 'efuse-hal-lib'.

+ 30 - 0
efuse-hal-lib/Makefile

@@ -0,0 +1,30 @@
+##
+ # Copyright (C) 2021 Alibaba Group Holding Limited
+##
+
+ifeq ("$(BUILD_SYSTEM)","YOCTO_BUILD")
+  export PATH_TO_SYSROOT=${SYSROOT_DIR}
+  export TOOLSCHAIN_PATH=${TOOLCHAIN_DIR}
+  export TOOLCHAIN_HOST=${CROSS_COMPILE}
+else
+  export PATH_TO_SYSROOT=${BUILDROOT_DIR}/output/host/riscv64-buildroot-linux-gnu/sysroot
+  export TOOLSCHAIN_PATH=${BUILDROOT_DIR}/output/host
+  export TOOLCHAIN_HOST=${TOOLSCHAIN_PATH}/bin/riscv64-unknown-linux-gnu-
+endif
+
+default: efuse_lib efuse_test
+
+efuse_lib:
+	make -C lib/src ARCH=$(ARCH) CROSS=$(CROSS_COMPILE)
+
+efuse_test: efuse_lib
+	make -C test/efuse_demo ARCH=$(ARCH) CROSS=$(CROSS_COMPILE)
+
+.PHONY: clean
+clean: clean_lib clean_test
+
+clean_lib:
+	make -C lib/src clean
+
+clean_test:
+	make -C test/efuse_demo clean

+ 1 - 0
efuse-hal-lib/README.txt

@@ -0,0 +1 @@
+The lib accomplishes all the functions which defined in <<HAL接口定义.xlsx>>

+ 22 - 0
efuse-hal-lib/lib/src/Makefile

@@ -0,0 +1,22 @@
+CC=$(CROSS)gcc
+CFLAGS:=-fpic
+LDFLAGS:=-shared -fpic
+SOURCE:=$(wildcard *.c)
+OBJS:=$(patsubst %.c,%.o,$(SOURCE))
+OUTDIR=../output
+TARGET_LIB:=libefuse.so
+
+
+all:$(OBJS)
+	echo $(OBJS)
+	mkdir -p $(OUTDIR)
+	$(CC) $(LDFLAGS) -o $(OUTDIR)/$(TARGET_LIB) $(OBJS)
+
+%.o:%.c
+	@echo Compiling $< ...
+	$(CC) -c $(CFLAGS) $< -o $*.o
+
+.PHONY: clean
+
+clean:
+	rm -rf $(OUTDIR)/$(TARGET_LIB) *.o

+ 377 - 0
efuse-hal-lib/lib/src/efuse-api.h

@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#ifndef _EFUSE_API_H
+#define _EFUSE_API_H
+
+typedef enum {
+	USR_DSP0_JTAG = 0,
+	USR_DSP1_JTAG,
+	USR_C910T_JTAG,
+	USR_C910R_JTAG,
+	USR_C906_JTAG,
+	USR_E902_JTAG,
+	USR_CHIP_DBG,
+	USR_DFT,
+} efuse_dbg_type_t;
+
+typedef enum {
+	DBG_MODE_ENABLE = 0,
+	DBG_MODE_PWD_PROTECT,
+	DBG_MODE_DISABLE,
+} efuse_dbg_mode_t;
+
+typedef enum {
+	BROM_USBBOOT_EN= 0,
+	BROM_USBBOOT_DIS = 0x5a5a5a5a,
+} brom_usbboot_st_t;
+
+typedef enum {
+	BROM_CCT_EN= 0,
+	BROM_CCT_DIS = 0x5a5a5a5a,
+} brom_cct_st_t;
+
+typedef enum {
+	IMAGE_ENCRYPT_DIS= 0,
+	IMAGE_ENCRYPT_EN = 0x5a5a5a5a,
+} img_encrypt_st_t;
+
+typedef enum {
+	SECURE_BOOT_DIS= 0,
+	SECURE_BOOT_EN = 0x5a5a5a5a,
+} sboot_st_t;
+
+/**
+ * csi_efuse_get_chipid() - Get chip id in eFuse
+ *
+ * @chip_id: pointer to the buffer to store chip id
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_chipid(void *chip_id);
+
+/**
+ * csi_efuse_get_user_dbg_mode() - Get debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	pointer to the buffer store debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t *dbg_mode);
+
+/**
+ * csi_efuse_set_user_dbg_mode() - Set debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t dbg_mode);
+
+/**
+ * csi_efuse_get_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_boot_offset(unsigned int *offset);
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_offset(unsigned int  offset);
+
+/**
+ * csi_efuse_get_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_boot_index(unsigned char *index);
+
+/**
+ * csi_efuse_set_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_index(unsigned char index);
+
+/**
+ * csi_efuse_get_bak_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_bak_boot_offset(unsigned int *offset);
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_offset(unsigned int  offset);
+
+/**
+ * csi_efuse_get_bak_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bak_boot_index(unsigned char *index);
+
+/**
+ * csi_efuse_set_bak_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_index(unsigned char index);
+
+/**
+ * csi_efuse_get_usr_brom_usb_fastboot_st() - Get bootrom  USB fastboots tatus in user area
+ *
+ * @status:	pointer to the buffer to store  USB fastboot status
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_usb_fastboot_st(brom_usbboot_st_t *status);
+
+/**
+ * csi_efuse_dis_usr_brom_usb_fastboot() - Disable bootrom USB fastboot status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_usb_fastboot(void);
+
+/**
+ * csi_efuse_get_usr_brom_cct_st() - Get bootrom CCT status in user area
+ *
+ * @status:	pointer to the buffer to store CCT
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_cct_st(brom_cct_st_t *status);
+
+/**
+ * csi_efuse_dis_usr_brom_cct() - Disable bootrom CCT status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_cct(void);
+
+/**
+ * csi_efuse_get_bl2_img_encrypt_st() - Get BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl2_img_encrypt_st() - Set BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl3_img_encrypt_st() - Get BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl3_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl3_img_encrypt_st() - Set BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL3 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl3_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl4_img_encrypt_st() - Get BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl4_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl4_img_encrypt_st() - Set BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl4_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl1_version() - Get BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl1_version(unsigned long long *version);
+
+/**
+ * csi_efuse_set_bl1_version() - Set BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl1_version(unsigned long long version);
+
+/**
+ * csi_efuse_get_bl2_version() - Get BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_version(unsigned long long *version);
+
+/**
+ * csi_efuse_set_bl2_version() - Set BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_version(unsigned long long version);
+
+/**
+ * csi_efuse_get_secure_boot_st() - Get seucre boot flag
+ *
+ * @sboot_flag:	A pointer to the buffer to store secure boot flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_secure_boot_st(sboot_st_t *sboot_flag);
+
+/**
+ * csi_efuse_get_hash_challenge() - Get hash challenge in eFuse
+ *
+ * @hash_resp:	pointer to the buffer to store hash response
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_hash_challenge(void * hash_resp);
+
+/**
+ * csi_efuse_get_userdata_group() - Get user data in corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_userdata_group(unsigned char *key, unsigned char block_num);
+
+/**
+ * csi_efuse_set_userdata_group() - Set user data corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_userdata_group(unsigned char *key, unsigned char block_num);
+
+/**
+ * csi_efuse_read() - Read data from eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data read from eFuse
+ * @cnt:	Number of bytes need to be read
+ *
+ * Return: number of data items read or error code
+*/
+int  csi_efuse_read(unsigned int offset, void *data, unsigned int cnt);
+
+/**
+ * csi_efuse_write() - Write data to eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data write to eFuse
+ * @cnt:	Number of bytes need to be write
+ *
+ * Return: number of data items write or error code
+*/
+int  csi_efuse_write(unsigned int offset, void *data, unsigned int cnt);
+
+/**
+ * csi_dbg_enable_c910t_jtag() - Enable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_enable_c910t_jtag(void);
+
+/**
+ * csi_dbg_disable_c910t_jtag() - Disable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_disable_c910t_jtag(void);
+
+/**
+ * csi_efuse_get_gmac_macaddr() - Get gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_get_gmac_macaddr(int dev_id, unsigned char *mac);
+
+/**
+ * csi_efuse_set_gmac_macaddr() - Set gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_set_gmac_macaddr(int dev_id, unsigned char *mac);
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RMA
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rma();
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RIP
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rip();
+
+#endif

+ 1507 - 0
efuse-hal-lib/lib/src/light-efuse-hal.c

@@ -0,0 +1,1507 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "efuse-api.h"
+
+//#define DEBUG_INFO
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x)			(sizeof(x) / sizeof((x)[0]))
+#endif
+
+#define EFUSE_LIT_BLOCK_BIT_WIDTH	128
+#define EFUSE_BIG_BLOCK_BIT_WIDTH	256
+#define EFUSE_BYTES_PER_LIT_BLOCK	(EFUSE_LIT_BLOCK_BIT_WIDTH >> 3)
+#define EFUSE_BYTES_PER_BIG_BLOCK	(EFUSE_BIG_BLOCK_BIT_WIDTH >> 3)
+
+struct func_efuse_info {
+	const char *func_name;
+	unsigned int block_id;
+	unsigned int addr;		/* in byte */
+	size_t	len;			/* in byte */
+	unsigned int shift;		/* left-shift bit within a byte*/
+	unsigned int mask;		/* mask within a byte */
+};
+
+struct func_efuse_info efuse_func_array[] = {
+	{"UID",				5,	0x50,	20,	0,	0xff},
+	{"USR_DSP0_JTAG_MODE",		8,	0x86,	1,	0,	0xff},
+	{"USR_DSP1_JTAG_MODE",		8,	0x87,	1,	0,	0xff},
+	{"USR_C910T_JTAG_MODE",		8,	0x88,	1,	0,	0xff},
+	{"USR_C910R_JTAG_MODE",		8,	0x89,	1,	0,	0xff},
+	{"USR_C906_JTAG_MODE",		8,	0x8a,	1,	0,	0xff},
+	{"USR_E902_JTAG_MODE",		8,	0x8b,	1,	0,	0xff},
+	{"USR_CHIP_DBG_MODE",		8,	0x8c,	1,	0,	0xff},
+	{"USR_DFT_MODE",		8,	0x8d,	1,	0,	0xff},
+	{"BOOT_OFFSET",			9,	0x90,	4,	0,	0xff},
+	{"BOOT_INDEX",			9,	0x94,	1,	0,	0xff},
+	{"BOOT_OFFSET_BAK",		9,	0x95,	4,	0,	0xff},
+	{"BOOT_INDEX_BAK",		9,	0x99,	1,	0,	0xff},
+	{"USR_USB_FASTBOOT_DIS",	9,	0x9a,	1,	4,	0x0f},
+	{"USR_BROM_CCT_DIS",		9,      0x9a,   1,      0,      0x0f},
+	{"IMAGE_BL2_ENC",		9,	0x9b,	1,	0,	0xff},
+	{"IMAGE_BL3_ENC",		9,	0x9c,	1,	0,	0xff},
+	{"IMAGE_BL4_ENC",		9,	0x9d,	1,	0,	0xff},
+	{"BL1VERSION",			10,	0xa0,	8,	0,	0xff},
+	{"BL2VERSION",			10,	0xa8,	8,	0,	0xff},
+	{"SECURE_BOOT",			1,	0x10,	1,	0,	0xff},
+	{"HASH_DEBUGPK",		25,	0x190,	32,	0,	0xff},
+	{"BROM_DCACHE_EN",		1,	0x12,	1,	2,	0x3},
+	{"GMAC0_MAC",			11,	0xb0,	6,	0,	0xff},
+	{"GMAC1_MAC",			11,	0xb8,	6,	0,	0xff},
+	{},
+};
+
+static const char *efuse_file = "/sys/bus/nvmem/devices/light-efuse0/nvmem";
+
+
+size_t efuse_read(int fd, void *buf, const char *func_name)
+{
+	unsigned int offset, mask, shift;
+	size_t len, ret;
+	int i, block;
+	const char *name;
+	off_t pos;
+
+	for (i = 0; i < ARRAY_SIZE(efuse_func_array); i++) {
+		if (!strcmp(func_name, efuse_func_array[i].func_name))
+			break;
+	}
+
+	if (i >= ARRAY_SIZE(efuse_func_array)) {
+		printf("invalid efuse function name(%s)\n", name);
+		return -EINVAL;
+	}
+
+	block	= efuse_func_array[i].block_id;
+	name	= efuse_func_array[i].func_name;
+	offset	= efuse_func_array[i].addr;
+	len	= efuse_func_array[i].len;
+	shift	= efuse_func_array[i].shift;
+	mask	= efuse_func_array[i].mask;
+#ifdef DEBUG_INFO
+	printf("[efuse info]: block: %d, name: %s, addr: 0x%x, len: %d mask: 0x%x\n",
+			block, name, offset, (int)len, mask);
+#endif
+	pos = lseek(fd, offset, SEEK_SET);
+	if (pos < 0) {
+		perror("failed to lseek offset to read");
+		return -errno;
+	}
+
+#ifdef DEBUG_INFO
+	printf("efuse pos = %p\n", pos);
+#endif
+	if (mask != 0xff) {
+		unsigned char data;
+		unsigned char rd_buf[len];
+
+		ret = read(fd, rd_buf, len);
+		if (ret != len) {
+#ifdef DEBUG_INFO
+			printf("real read len: %d, expected read len: %d\n", ret, len);
+#endif
+			perror("failed to read");
+			ret = -errno;
+			goto out;
+		}
+		data = (rd_buf[0] >> shift) & mask;
+#ifdef DEBUG_INFO
+		printf("data = 0x%x\n", data);
+#endif
+		memcpy(buf, &data, 1);
+
+		if (len > 1) {
+			len = len - 1;
+			buf = (unsigned char *)buf + 1;
+			memcpy(buf, &rd_buf[1], len);
+		}
+	} else { /* mask == 0xff */
+		ret = read(fd, buf, len);
+		if (ret != len) {
+#ifdef DEBUG_INFO
+			printf("real read len: %d, expected read len: %d\n", ret, len);
+#endif
+			perror("failed to read");
+			ret = -errno;
+		}
+	}
+
+out:
+	return ret;
+}
+
+size_t efuse_write(int fd, const void *buf, const char *func_name)
+{
+	unsigned int offset, mask, shift;
+	size_t len, ret;
+	int i, block;
+	const char *name;
+	off_t pos;
+
+	for (i = 0; i < ARRAY_SIZE(efuse_func_array); i++) {
+		if (!strcmp(func_name, efuse_func_array[i].func_name))
+			break;
+	}
+
+	if (i >= ARRAY_SIZE(efuse_func_array)) {
+		printf("invalid efuse function name(%s)\n", name);
+		return -EINVAL;
+	}
+
+	block	= efuse_func_array[i].block_id;
+	name	= efuse_func_array[i].func_name;
+	offset	= efuse_func_array[i].addr;
+	len	= efuse_func_array[i].len;
+	shift	= efuse_func_array[i].shift;
+	mask	= efuse_func_array[i].mask;
+#ifdef DEBUG_INFO
+	printf("efuse info: block: %d, name: %s, addr: 0x%x, len: %d, mask: 0x%x\n",
+			block, name, offset, (int)len, mask);
+#endif
+
+	pos = lseek(fd, offset, SEEK_SET);
+	if (pos < 0) {
+		perror("failed to lseek offset to read");
+		return -errno;
+	}
+#ifdef DEBUG_INFO
+	printf("efuse pos = %p\n", pos);
+#endif
+	if (mask != 0xff) {
+		unsigned char data;
+		unsigned char wr_buf[len];
+
+		memcpy(wr_buf, buf, len);
+
+		ret = read(fd, &data, 1);
+		if (ret < 0) {
+			perror("failed to read");
+			ret = -errno;
+			goto out;
+		}
+
+		data &= ~(mask << shift);
+		data |= (wr_buf[0] & mask) << shift;
+		memcpy(&wr_buf[0], &data, 1);
+
+		if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+			perror("failed to lseek offset to write");
+			ret = -errno;
+			goto out;
+		}
+
+		ret = write(fd, wr_buf, len);
+		if (ret != len) {
+			perror("failed to write");
+			ret = -errno;
+		}
+	} else { /* mask == 0xff */
+		ret = write(fd, buf, len);
+		if (ret != len) {
+			perror("failed to write");
+			ret = -errno;
+		}
+	}
+
+out:
+	return ret;
+}
+
+/* according to FuseMap_v1.2.1.xlsx */
+size_t efuse_block_read(int fd, unsigned char *buf, unsigned int block_num)
+{
+	unsigned int width, offset, bytes;
+	size_t ret;
+
+	if (block_num >= 42 && block_num <= 47)
+		width = EFUSE_BIG_BLOCK_BIT_WIDTH;
+	else
+		width = EFUSE_LIT_BLOCK_BIT_WIDTH;
+
+	if (block_num <= 42)
+		offset = block_num * EFUSE_BYTES_PER_LIT_BLOCK;
+	else if (block_num > 42 && block_num <= 48)
+		offset = 42 * EFUSE_BYTES_PER_LIT_BLOCK + (block_num - 42) * EFUSE_BYTES_PER_BIG_BLOCK;
+	else
+		offset = 42 * EFUSE_BYTES_PER_LIT_BLOCK + 6 * EFUSE_BYTES_PER_BIG_BLOCK +
+			(block_num - 48) * EFUSE_BYTES_PER_LIT_BLOCK;
+
+	bytes = width / 8;
+
+	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+		perror("failed to lseek offset to read");
+		return -errno;
+	}
+
+	ret = read(fd, buf, bytes);
+	if (ret != bytes) {
+		perror("failed to read");
+		ret = -errno;
+	}
+
+	return ret;
+}
+
+/* according to FuseMap_v1.2.1.xlsx */
+size_t efuse_block_write(int fd, unsigned char *buf, unsigned int block_num)
+{
+	unsigned int width, offset, bytes;
+	size_t ret;
+
+	if (block_num >= 42 && block_num <= 47)
+		width = EFUSE_BIG_BLOCK_BIT_WIDTH;
+	else
+		width = EFUSE_LIT_BLOCK_BIT_WIDTH;
+
+	if (block_num <= 42)
+		offset = block_num * EFUSE_BYTES_PER_LIT_BLOCK;
+	else if (block_num > 42 && block_num <= 48)
+		offset = 42 * EFUSE_BYTES_PER_LIT_BLOCK + (block_num - 42) * EFUSE_BYTES_PER_BIG_BLOCK;
+	else
+		offset = 42 * EFUSE_BYTES_PER_LIT_BLOCK + 6 * EFUSE_BYTES_PER_BIG_BLOCK +
+			(block_num - 48) * EFUSE_BYTES_PER_LIT_BLOCK;
+
+	bytes = width / 8;
+
+	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+		perror("failed to lseek offset to write");
+		return -errno;
+	}
+
+	ret = write(fd, buf, bytes);
+	if (ret != bytes) {
+		perror("failed to write");
+		ret = -errno;
+	}
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_chipid() - Get chip id in eFuse
+ *
+ * @chip_id: pointer to the buffer to store chip id
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_chipid(void *chip_id)
+{
+	int ret, fd;
+
+	assert(chip_id);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		perror("open");
+		return -errno;
+	}
+
+	ret = efuse_read(fd, chip_id, "UID");
+	if (ret < 0)
+		printf("failed to get 'UID' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_user_dbg_mode() - Get debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	pointer to the buffer store debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t *dbg_mode)
+{
+	int ret, fd;
+	char *mode_name;
+
+	assert(dbg_mode);
+	if ((type != USR_DSP0_JTAG) && (type != USR_DSP1_JTAG) &&
+			(type != USR_C910T_JTAG) && (type != USR_C910R_JTAG) &&
+			(type != USR_C906_JTAG) && (type != USR_E902_JTAG) &&
+			(type != USR_CHIP_DBG) && (type != USR_DFT))
+
+		return -EINVAL;
+
+	switch (type) {
+	case USR_DSP0_JTAG:
+		mode_name = "USR_DSP0_JTAG_MODE";
+		break;
+	case USR_DSP1_JTAG:
+		mode_name = "USR_DSP1_JTAG_MODE";
+		break;
+	case USR_C910T_JTAG:
+		mode_name = "USR_C910T_JTAG_MODE";
+		break;
+	case USR_C910R_JTAG:
+		mode_name = "USR_C910R_JTAG_MODE";
+		break;
+	case USR_C906_JTAG:
+		mode_name = "USR_C906_JTAG_MODE";
+		break;
+	case USR_E902_JTAG:
+		mode_name = "USR_E902_JTAG_MODE";
+		break;
+	case USR_CHIP_DBG:
+		mode_name = "USR_CHIP_DBG_MODE";
+		break;
+	case USR_DFT:
+		mode_name = "USR_DFT_MODE";
+		break;
+	}
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, dbg_mode, mode_name);
+	if (ret < 0)
+		printf("failed to get %s from efuse\n", mode_name);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_user_dbg_mode() - Set debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t dbg_mode)
+{
+	int ret, fd;
+	char *mode_name;
+
+	if ((type != USR_DSP0_JTAG) && (type != USR_DSP1_JTAG) &&
+			(type != USR_C910T_JTAG) && (type != USR_C910R_JTAG) &&
+			(type != USR_C906_JTAG) && (type != USR_E902_JTAG) &&
+			(type != USR_CHIP_DBG) && (type != USR_DFT))
+		return -EINVAL;
+
+	if ((dbg_mode != DBG_MODE_ENABLE) && (dbg_mode != DBG_MODE_PWD_PROTECT) &&
+			(dbg_mode != DBG_MODE_DISABLE))
+		return -EINVAL;
+
+	switch (type) {
+	case USR_DSP0_JTAG:
+		mode_name = "USR_DSP0_JTAG_MODE";
+		break;
+	case USR_DSP1_JTAG:
+		mode_name = "USR_DSP1_JTAG_MODE";
+		break;
+	case USR_C910T_JTAG:
+		mode_name = "USR_C910T_JTAG_MODE";
+		break;
+	case USR_C910R_JTAG:
+		mode_name = "USR_C910R_JTAG_MODE";
+		break;
+	case USR_C906_JTAG:
+		mode_name = "USR_C906_JTAG_MODE";
+		break;
+	case USR_E902_JTAG:
+		mode_name = "USR_E902_JTAG_MODE";
+		break;
+	case USR_CHIP_DBG:
+		mode_name = "USR_CHIP_DBG_MODE";
+		break;
+	case USR_DFT:
+		mode_name = "USR_DFT_MODE";
+		break;
+	}
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, (unsigned char *)&dbg_mode, mode_name);
+	if (ret < 0)
+		printf("failed to set %s into efuse\n", mode_name);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_boot_offset(unsigned int *offset)
+{
+	int ret, fd;
+
+	assert(offset);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, offset, "BOOT_OFFSET");
+	if (ret < 0)
+		printf("failed to get 'BOOT_OFFSET' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_offset(unsigned int  offset)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &offset, "BOOT_OFFSET");
+	if (ret < 0)
+		printf("failed to set 'BOOT_OFFSET' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_boot_index(unsigned char *index)
+{
+	int ret, fd;
+
+	assert(index);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, index, "BOOT_INDEX");
+	if (ret < 0)
+		printf("failed to get 'BOOT_INDEX' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_index(const unsigned char index)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &index, "BOOT_INDEX");
+	if (ret < 0)
+		printf("failed to set 'BOOT_INDEX' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bak_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_bak_boot_offset(unsigned int *offset)
+{
+	int ret, fd;
+
+	assert(offset);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, offset, "BOOT_OFFSET_BAK");
+	if (ret < 0)
+		printf("failed to get 'BOOT_OFFSET_BAK' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_offset(unsigned int  offset)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &offset, "BOOT_OFFSET_BAK");
+	if (ret < 0)
+		printf("failed to set 'BOOT_OFFSET_BAK' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bak_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bak_boot_index(unsigned char *index)
+{
+	int ret, fd;
+
+	assert(index);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, index, "BOOT_INDEX_BAK");
+	if (ret < 0)
+		printf("failed to get 'BOOT_INDEX_BAK' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bak_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_index(unsigned char index)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &index, "BOOT_INDEX_BAK");
+	if (ret < 0)
+		printf("failed to set 'BOOT_INDEX_BAK' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_usr_brom_usb_fastboot_st() - Get bootrom  USB fastboots tatus in user area
+ *
+ * @status:	pointer to the buffer to store  USB fastboot status
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_usb_fastboot_st(brom_usbboot_st_t *status)
+{
+	int ret, fd;
+	unsigned char tempdata;
+	assert(status);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "USR_USB_FASTBOOT_DIS");
+	if (ret < 0)
+		printf("failed to get 'USR_USB_FASTBOOT_DIS' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0xa)
+		*status = BROM_USBBOOT_DIS;
+	else if (tempdata != BROM_USBBOOT_EN)
+		ret = -EINVAL;
+	else
+		*status = BROM_USBBOOT_EN;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_dis_usr_brom_usb_fastboot() - Disable bootrom USB fastboot status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_usb_fastboot(void)
+{
+	int ret, fd;
+	unsigned char status = 0xA;	/* disable value */
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &status, "USR_USB_FASTBOOT_DIS");
+	if (ret < 0)
+		printf("failed to set 'USR_USB_FASTBOOT_DIS' status into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_usr_brom_cct_st() - Get bootrom CCT status in user area
+ *
+ * @status:	pointer to the buffer to store CCT
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_cct_st(brom_cct_st_t *status)
+{
+	int ret, fd;
+	unsigned char tempdata;
+
+	assert(status);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "USR_BROM_CCT_DIS");
+	if (ret < 0)
+		printf("failed to get 'USR_BROM_CCT_DIS' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0xa)
+		*status = BROM_CCT_DIS;
+	else if(tempdata != BROM_CCT_EN)
+		ret = -EINVAL;
+	else
+		*status = BROM_CCT_EN;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_dis_usr_brom_cct() - Disable bootrom CCT status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_cct(void)
+{
+	int ret, fd;
+	unsigned char status = 0xA;	/* disable value */
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &status, "USR_BROM_CCT_DIS");
+	if (ret < 0)
+		printf("failed to set 'USR_BROM_CCT_DIS' status into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bl2_img_encrypt_st() - Get BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_img_encrypt_st(img_encrypt_st_t *encrypt_flag)
+{
+	int ret, fd;
+	unsigned char tempdata;
+
+	assert(encrypt_flag);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "IMAGE_BL2_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL2_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0x5a)
+		*encrypt_flag = IMAGE_ENCRYPT_EN;
+	else if (tempdata != IMAGE_ENCRYPT_DIS)
+		ret = -EINVAL;
+	else
+		*encrypt_flag = IMAGE_ENCRYPT_DIS;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bl2_img_encrypt_st() - Set BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_img_encrypt_st(img_encrypt_st_t encrypt_flag)
+{
+	int ret, fd;
+
+	if ((encrypt_flag != IMAGE_ENCRYPT_DIS) && (encrypt_flag != IMAGE_ENCRYPT_EN))
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	if (encrypt_flag == IMAGE_ENCRYPT_EN)
+		encrypt_flag = 0x5a;
+
+	ret = efuse_write(fd, (unsigned char *)&encrypt_flag, "IMAGE_BL2_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL2_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bl3_img_encrypt_st() - Get BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl3_img_encrypt_st(img_encrypt_st_t *encrypt_flag)
+{
+	int ret, fd;
+	unsigned char tempdata;
+
+	assert(encrypt_flag);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "IMAGE_BL3_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL3_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0x5a)
+		*encrypt_flag = IMAGE_ENCRYPT_EN;
+	else if (tempdata != IMAGE_ENCRYPT_DIS)
+		ret = -EINVAL;
+	else
+		*encrypt_flag = IMAGE_ENCRYPT_DIS;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bl3_img_encrypt_st() - Set BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL3 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl3_img_encrypt_st(img_encrypt_st_t encrypt_flag)
+{
+	int ret, fd;
+
+	if ((encrypt_flag != IMAGE_ENCRYPT_DIS) && (encrypt_flag != IMAGE_ENCRYPT_EN))
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	if (encrypt_flag == IMAGE_ENCRYPT_EN)
+		encrypt_flag = 0x5a;
+
+	ret = efuse_write(fd, (unsigned char *)&encrypt_flag, "IMAGE_BL3_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL3_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bl4_img_encrypt_st() - Get BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl4_img_encrypt_st(img_encrypt_st_t *encrypt_flag)
+{
+	int ret, fd;
+	unsigned char tempdata;
+
+	assert(encrypt_flag);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "IMAGE_BL4_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL4_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0x5a)
+		*encrypt_flag = IMAGE_ENCRYPT_EN;
+	else if (tempdata != IMAGE_ENCRYPT_DIS)
+		ret = -EINVAL;
+	else
+		*encrypt_flag = IMAGE_ENCRYPT_DIS;
+
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bl4_img_encrypt_st() - Set BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl4_img_encrypt_st(img_encrypt_st_t encrypt_flag)
+{
+	int ret, fd;
+
+	if ((encrypt_flag != IMAGE_ENCRYPT_DIS) && (encrypt_flag != IMAGE_ENCRYPT_EN))
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	if (encrypt_flag == IMAGE_ENCRYPT_EN)
+		encrypt_flag = 0x5a;
+
+	ret = efuse_write(fd, (unsigned char *)&encrypt_flag, "IMAGE_BL4_ENC");
+	if (ret < 0)
+		printf("failed to get 'IMAGE_BL4_ENC' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bl1_version() - Get BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl1_version(unsigned long long *version)
+{
+	int ret, fd;
+
+	assert(version);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, version, "BL1VERSION");
+	if (ret < 0)
+		printf("failed to get 'BL1VERSION' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bl1_version() - Set BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl1_version(unsigned long long version)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &version, "BL1VERSION");
+	if (ret < 0)
+		printf("failed to set 'BL1VERSION' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_bl2_version() - Get BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_version(unsigned long long *version)
+{
+	int ret, fd;
+
+	assert(version);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, version, "BL2VERSION");
+	if (ret < 0)
+		printf("failed to get 'BL2VERSION' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_bl2_version() - Set BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_version(unsigned long long version)
+{
+	int ret, fd;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_write(fd, &version, "BL2VERSION");
+	if (ret < 0)
+		printf("failed to set 'BL2VERSION' into efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_secure_boot_st() - Get seucre boot flag
+ *
+ * @sboot_flag:	A pointer to the buffer to store secure boot flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_secure_boot_st(sboot_st_t *sboot_flag)
+{
+	int ret, fd;
+	unsigned char tempdata;
+
+	assert(sboot_flag);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, &tempdata, "SECURE_BOOT");
+	if (ret < 0)
+		printf("failed to get 'SECURE_BOOT' from efuse\n");
+	else
+		ret = 0;
+
+	if (tempdata == 0x5a)
+		*sboot_flag = SECURE_BOOT_EN;
+	else if (tempdata != SECURE_BOOT_DIS)
+		ret = -EINVAL;
+	else
+		*sboot_flag = SECURE_BOOT_DIS;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_hash_challenge() - Get hash challenge in eFuse
+ *
+ * @hash_resp:	pointer to the buffer to store hash response
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_hash_challenge(void * hash_resp)
+{
+	int ret, fd;
+
+	assert(hash_resp);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_read(fd, hash_resp, "HASH_DEBUGPK");
+	if (ret < 0)
+		printf("failed to get 'HASH_DEBUGPK' from efuse\n");
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_get_userdata_group() - Get user data in corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_userdata_group(unsigned char *key, unsigned char block_num)
+{
+	int ret, fd;
+
+	assert(key);
+	if (block_num >= 58)
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_block_read(fd, key, block_num);
+	if (ret < 0)
+		printf("failed to get block%d data from efuse\n", block_num);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_userdata_group() - Set user data corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_userdata_group(unsigned char *key, unsigned char block_num)
+{
+	int ret, fd;
+
+	assert(key);
+	if (block_num > 58) {
+		printf("the block number is out of the scop \n");
+		return -EINVAL;
+	}
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	ret = efuse_block_write(fd, key, block_num);
+	if (ret < 0)
+		printf("failed to set block%d data into efuse\n", block_num);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_read() - Read data from eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data read from eFuse
+ * @cnt:	Number of bytes need to be read
+ *
+ * Return: number of data items read or error code
+*/
+int  csi_efuse_read(unsigned int offset, void *data, unsigned int cnt)
+{
+	int ret, fd;
+
+	assert(data);
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+		perror("failed to lseek offset to read");
+		close(fd);
+		return -errno;
+	}
+
+	ret = read(fd, data, cnt);
+	if (ret < 0) {
+		perror("failed to read data from efuse");
+		ret = -errno;
+	}
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_write() - Write data to eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data write to eFuse
+ * @cnt:	Number of bytes need to be write
+ *
+ * Return: number of data items write or error code
+*/
+int  csi_efuse_write(unsigned int offset, void *data, unsigned int cnt)
+{
+	int ret, fd;
+
+	assert(data);
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+		perror("failed to lseek offset to write");
+		close(fd);
+		return -errno;
+	}
+
+	ret = write(fd, data, cnt);
+	if (ret < 0) {
+		perror("failed to write data to efuse");
+		ret = -errno;
+	}
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_dbg_enable_c910t_jtag() - Enable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_enable_c910t_jtag(void)
+{
+
+}
+
+/**
+ * csi_dbg_disable_c910t_jtag() - Disable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_disable_c910t_jtag(void)
+{
+
+}
+
+/**
+ * csi_efuse_get_gmac_macaddr() - Get gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_get_gmac_macaddr(int dev_id, unsigned char *mac)
+{
+	int ret, fd;
+	char gmac_name[12] = {};
+
+	assert(mac);
+	if ((dev_id != 0) && (dev_id != 1))
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDONLY);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	sprintf(gmac_name, "GMAC%d_MAC", dev_id);
+
+	ret = efuse_read(fd, mac, gmac_name);
+	if (ret < 0)
+		printf("failed to get %s\n", gmac_name);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_set_gmac_macaddr() - Set gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_set_gmac_macaddr(int dev_id, unsigned char *mac)
+{
+	int ret, fd;
+	char gmac_name[12] = {};
+
+	assert(mac);
+	if ((dev_id != 0) && (dev_id != 1))
+		return -EINVAL;
+
+	fd = open(efuse_file, O_RDWR);
+	if (fd < 0) {
+		printf("failed to open efuse device: %s\n", efuse_file);
+		return -errno;
+	}
+
+	sprintf(gmac_name, "GMAC%d_MAC", dev_id);
+
+	ret = efuse_write(fd, mac, gmac_name);
+	if (ret < 0)
+		printf("failed to set '%s' into efuse\n", gmac_name);
+	else
+		ret = 0;
+
+	close(fd);
+
+	return ret;
+}
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RMA
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rma()
+{
+	int fd, ret;
+	char d = '1';
+	const char *dev_path = "/sys/devices/platform/soc/ffff210000.efuse/rma_lc";
+
+	fd = open(dev_path, O_WRONLY);
+	if (fd < 0) {
+		printf("failed to open device '%s'\n", dev_path);
+		return -errno;
+	}
+	ret = write(fd, &d, 1);
+	if (ret < 0){
+		printf("failed to update rma lifecycle\n");
+		return -errno;
+	} else {
+		ret = 0;
+	}
+	close(fd);
+
+	return 0;
+}
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RIP
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rip()
+{
+	int fd, ret;
+	char d = '1';
+	const char *dev_path = "/sys/devices/platform/soc/ffff210000.efuse/rip_lc";
+
+	fd = open(dev_path, O_WRONLY);
+	if (fd < 0) {
+		printf("failed to open device '%s'\n", dev_path);
+		return -errno;
+	}
+	ret = write(fd, &d, 1);
+	if (ret < 0){
+		printf("failed to update rip lifecycle\n");
+		return -errno;
+	} else {
+		ret = 0;
+	}
+	close(fd);
+
+	return 0;
+}
+

BIN
efuse-hal-lib/lib/src/light-efuse-hal.o


+ 22 - 0
efuse-hal-lib/test/efuse_demo/Makefile

@@ -0,0 +1,22 @@
+CC=$(CROSS)gcc
+CFLAGS=-DxDEBUG
+LIBS=-L ../../lib/output -lefuse
+
+BIN = efuse_demo
+OUTDIR = ../output
+SRCS:=$(wildcard *.c)
+COBJS:=$(SRCS:.c=.o)
+
+all:$(OUTDIR)/$(BIN)
+
+$(OUTDIR)/$(BIN):$(COBJS)
+	mkdir -p $(OUTDIR)
+	$(CC) -o $(OUTDIR)/$(BIN) $(CFLAGS) $(COBJS) $(LIBS)
+
+$(COBJS): %.o: %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+.PHONY: clean
+
+clean:
+	rm -rf $(OUTDIR)/$(BIN) $(COBJS)

+ 377 - 0
efuse-hal-lib/test/efuse_demo/efuse-api.h

@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#ifndef _EFUSE_API_H
+#define _EFUSE_API_H
+
+typedef enum {
+	USR_DSP0_JTAG = 0,
+	USR_DSP1_JTAG,
+	USR_C910T_JTAG,
+	USR_C910R_JTAG,
+	USR_C906_JTAG,
+	USR_E902_JTAG,
+	USR_CHIP_DBG,
+	USR_DFT,
+} efuse_dbg_type_t;
+
+typedef enum {
+	DBG_MODE_ENABLE = 0,
+	DBG_MODE_PWD_PROTECT,
+	DBG_MODE_DISABLE,
+} efuse_dbg_mode_t;
+
+typedef enum {
+	BROM_USBBOOT_EN= 0,
+	BROM_USBBOOT_DIS = 0x5a5a5a5a,
+} brom_usbboot_st_t;
+
+typedef enum {
+	BROM_CCT_EN= 0,
+	BROM_CCT_DIS = 0x5a5a5a5a,
+} brom_cct_st_t;
+
+typedef enum {
+	IMAGE_ENCRYPT_DIS= 0,
+	IMAGE_ENCRYPT_EN = 0x5a5a5a5a,
+} img_encrypt_st_t;
+
+typedef enum {
+	SECURE_BOOT_DIS= 0,
+	SECURE_BOOT_EN = 0x5a5a5a5a,
+} sboot_st_t;
+
+/**
+ * csi_efuse_get_chipid() - Get chip id in eFuse
+ *
+ * @chip_id: pointer to the buffer to store chip id
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_chipid(void *chip_id);
+
+/**
+ * csi_efuse_get_user_dbg_mode() - Get debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	pointer to the buffer store debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t *dbg_mode);
+
+/**
+ * csi_efuse_set_user_dbg_mode() - Set debug mode in user area
+ *
+ * @type:	Debug type
+ *
+ * @dbg_mode:	debug mode
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_user_dbg_mode(efuse_dbg_type_t type, efuse_dbg_mode_t dbg_mode);
+
+/**
+ * csi_efuse_get_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_boot_offset(unsigned int *offset);
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_offset(unsigned int  offset);
+
+/**
+ * csi_efuse_get_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_boot_index(unsigned char *index);
+
+/**
+ * csi_efuse_set_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_boot_index(unsigned char index);
+
+/**
+ * csi_efuse_get_bak_boot_offset() - Get BL1's offset in boot media
+ *
+ * @offset:	pointer to the buffer to store BL1's offset
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_efuse_get_bak_boot_offset(unsigned int *offset);
+
+/**
+ * csi_efuse_set_boot_offset() - Set BL1's offset in boot media
+ *
+ * @offset:	Offset value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_offset(unsigned int  offset);
+
+/**
+ * csi_efuse_get_bak_boot_index() - Get BL1's index in boot media
+ *
+ * @index:	pointer to the buffer to store BL1's index
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bak_boot_index(unsigned char *index);
+
+/**
+ * csi_efuse_set_bak_boot_index() - Set BL1's index in boot media
+ *
+ * @index:	index value to be set
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bak_boot_index(unsigned char index);
+
+/**
+ * csi_efuse_get_usr_brom_usb_fastboot_st() - Get bootrom  USB fastboots tatus in user area
+ *
+ * @status:	pointer to the buffer to store  USB fastboot status
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_usb_fastboot_st(brom_usbboot_st_t *status);
+
+/**
+ * csi_efuse_dis_usr_brom_usb_fastboot() - Disable bootrom USB fastboot status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_usb_fastboot(void);
+
+/**
+ * csi_efuse_get_usr_brom_cct_st() - Get bootrom CCT status in user area
+ *
+ * @status:	pointer to the buffer to store CCT
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_usr_brom_cct_st(brom_cct_st_t *status);
+
+/**
+ * csi_efuse_dis_usr_brom_cct() - Disable bootrom CCT status in user area
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_dis_usr_brom_cct(void);
+
+/**
+ * csi_efuse_get_bl2_img_encrypt_st() - Get BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl2_img_encrypt_st() - Set BL2 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl3_img_encrypt_st() - Get BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL2 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl3_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl3_img_encrypt_st() - Set BL3 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL3 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl3_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl4_img_encrypt_st() - Get BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl4_img_encrypt_st( img_encrypt_st_t *encrypt_flag);
+
+/**
+ * csi_efuse_set_bl4_img_encrypt_st() - Set BL4 image encryption flag
+ *
+ * @encrypt_flag:	pointer to the buffer to store BL4 encryption flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl4_img_encrypt_st( img_encrypt_st_t encrypt_flag);
+
+/**
+ * csi_efuse_get_bl1_version() - Get BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl1_version(unsigned long long *version);
+
+/**
+ * csi_efuse_set_bl1_version() - Set BL1 version
+ *
+ * @version:	pointer to the buffer to store BL1's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl1_version(unsigned long long version);
+
+/**
+ * csi_efuse_get_bl2_version() - Get BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_bl2_version(unsigned long long *version);
+
+/**
+ * csi_efuse_set_bl2_version() - Set BL2 version
+ *
+ * @version:	pointer to the buffer to store BL2's version in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_bl2_version(unsigned long long version);
+
+/**
+ * csi_efuse_get_secure_boot_st() - Get seucre boot flag
+ *
+ * @sboot_flag:	A pointer to the buffer to store secure boot flag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_secure_boot_st(sboot_st_t *sboot_flag);
+
+/**
+ * csi_efuse_get_hash_challenge() - Get hash challenge in eFuse
+ *
+ * @hash_resp:	pointer to the buffer to store hash response
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_hash_challenge(void * hash_resp);
+
+/**
+ * csi_efuse_get_userdata_group() - Get user data in corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_get_userdata_group(unsigned char *key, unsigned char block_num);
+
+/**
+ * csi_efuse_set_userdata_group() - Set user data corresponding eFuse block
+ *
+ * @key:	pointer to the buffer to store user data
+ * @block_num:	the block number in eFuse
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int  csi_efuse_set_userdata_group(unsigned char *key, unsigned char block_num);
+
+/**
+ * csi_efuse_read() - Read data from eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data read from eFuse
+ * @cnt:	Number of bytes need to be read
+ *
+ * Return: number of data items read or error code
+*/
+int  csi_efuse_read(unsigned int offset, void *data, unsigned int cnt);
+
+/**
+ * csi_efuse_write() - Write data to eFuse
+ *
+ * @offset:	offset address
+ * @data:	Pointer to a buffer storing the data write to eFuse
+ * @cnt:	Number of bytes need to be write
+ *
+ * Return: number of data items write or error code
+*/
+int  csi_efuse_write(unsigned int offset, void *data, unsigned int cnt);
+
+/**
+ * csi_dbg_enable_c910t_jtag() - Enable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_enable_c910t_jtag(void);
+
+/**
+ * csi_dbg_disable_c910t_jtag() - Disable C910 TEE core jtag
+ *
+ * Return: 0 on success or negative code on failure
+*/
+int csi_dbg_disable_c910t_jtag(void);
+
+/**
+ * csi_efuse_get_gmac_macaddr() - Get gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_get_gmac_macaddr(int dev_id, unsigned char *mac);
+
+/**
+ * csi_efuse_set_gmac_macaddr() - Set gmac0/gmac1 mac address in eFuse
+ * @dev_id: '0' means gmac0, '1' means gmac1
+ * @mac: the mac address string
+ *
+ * Return: 0: Success others: Failed
+*/
+int csi_efuse_set_gmac_macaddr(int dev_id, unsigned char *mac);
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RMA
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rma();
+
+/**
+ * csi_efuse_update_lc_rma() - Upate efuse life cycle RIP
+ *
+ * Return: 0: Success others: Failed
+ */
+int csi_efuse_update_lc_rip();
+
+#endif

+ 470 - 0
efuse-hal-lib/test/efuse_demo/light-efuse-test.c

@@ -0,0 +1,470 @@
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "efuse-api.h"
+
+void csi_efuse_offset_test()
+{
+	int ret, i;
+	unsigned char data[32] = {0xff, 0xef, 0xdf, 0xcf, 0xbf, 0xaf, 0x9f, 0x8f, 0x7f, 0x6f, 0x5f, 0x4f, 0x3f, 0x2f, 0x1f, 0x0f, 0xfe, 0xee, 0xde, 0xce, 0xbe, 0xae, 0x9e, 0x8e, 0x7e, 0x6e, 0x5e, 0x4e, 0x3e, 0x2e, 0x3f, 0xff};
+	unsigned int addr = 50;
+
+	printf("data before set:\n");
+
+	for (i = 0; i < 32; i++)
+		printf("0x%x ", data[i]);
+	printf("\n");
+
+#if 1
+	ret = csi_efuse_write(addr, &data, sizeof(data));
+	if (ret < 0)
+		return;
+	memset(data, 0, 32);
+#endif
+	ret = csi_efuse_read(addr, &data, sizeof(data));
+	if (ret < 0)
+		return;
+
+	printf("data after set:\n");
+
+	for (i = 0; i < 32; i++)
+		printf("0x%x ", data[i]);
+	printf("\n");
+}
+
+void csi_efuse_userdata_group_test()
+{
+	unsigned char group[16] = {0};
+	int ret, i;
+
+	for (i = 0; i < 16; i++)
+		group[i] = i;
+
+	ret = csi_efuse_set_userdata_group(group, 12);
+	if (ret < 0)
+		return;
+
+	memset(group, 0, sizeof(group));
+
+	ret = csi_efuse_get_userdata_group(group, 12);
+	if (ret < 0)
+		return;
+#if 0
+	for (i = 0; i < 16; i++)
+		printf("%x", group[i]);
+
+	ret = csi_efuse_set_userdata_group(group, 44);
+	if (ret < 0)
+		return;
+#endif
+	memset(group, 0, sizeof(group));
+
+	ret = csi_efuse_get_userdata_group(group, 44);
+	if (ret < 0)
+		return;
+
+	for (i = 0; i < 16; i++)
+		printf("%x", group[i]);
+
+	printf("\n");
+}
+
+void csi_efuse_get_hash_challenge_test()
+{
+	unsigned char hash[32] = {0};
+	int ret, i;
+
+	ret =csi_efuse_get_hash_challenge(&hash);
+	if (ret < 0)
+		return;
+
+	printf("hash challenge: 0x");
+	for (i = 31; i >=0; i--)
+		printf("%x", hash[i]);
+	printf("\n");
+}
+
+void csi_efuse_get_secure_boot_st_test()
+{
+	sboot_st_t flag;
+	int ret;
+
+	ret =csi_efuse_get_secure_boot_st(&flag);
+	if (ret < 0)
+		return;
+	printf("secure boot flag: 0x%x\n", flag);
+
+	if (flag != SECURE_BOOT_DIS && flag != SECURE_BOOT_EN)
+		printf("incorrect secure boot flag\n");
+}
+
+void csi_efuse_get_bl2_version_test()
+{
+	unsigned long long version;
+	int ret;
+
+	ret = csi_efuse_get_bl2_version(&version);
+	if (ret < 0)
+		return;
+	printf("before setting bl2 version = 0x%llx\n", version);
+
+	version = 0xabcdef123456789a;
+	ret = csi_efuse_set_bl2_version(version);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bl2_version(&version);
+	if (ret < 0)
+		return;
+	printf("after setting bl2 version = 0x%llx\n", version);
+}
+
+void csi_efuse_get_bl1_version_test()
+{
+	unsigned long long version;
+	int ret;
+
+	ret = csi_efuse_get_bl1_version(&version);
+	if (ret < 0)
+		return;
+	printf("before setting bl1 version = 0x%llx\n", version);
+
+	version = 0xabcdef123456789a;
+	ret = csi_efuse_set_bl1_version(version);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bl1_version(&version);
+	if (ret < 0)
+		return;
+	printf("after setting bl1 version = 0x%llx\n", version);
+}
+
+void csi_efuse_bl4_img_encrypt_test()
+{
+	img_encrypt_st_t flag;
+	int ret;
+
+	ret = csi_efuse_get_bl4_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("before setting bl4 img flg: 0x%x\n", flag);
+
+	flag = IMAGE_ENCRYPT_EN;
+	ret = csi_efuse_set_bl4_img_encrypt_st(flag);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bl4_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("after setting bl4 img flg: 0x%x\n", flag);
+}
+
+void csi_efuse_bl3_img_encrypt_test()
+{
+	img_encrypt_st_t flag;
+	int ret;
+
+	ret = csi_efuse_get_bl3_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("before setting bl3 img flg: 0x%x\n", flag);
+
+	flag = IMAGE_ENCRYPT_EN;
+	ret = csi_efuse_set_bl3_img_encrypt_st(flag);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bl3_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("after setting bl3 img flg: 0x%x\n", flag);
+}
+
+void csi_efuse_bl2_img_encrypt_test()
+{
+	img_encrypt_st_t flag;
+	int ret;
+
+	ret = csi_efuse_get_bl2_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("before setting bl2 img flg: 0x%x\n", flag);
+
+	flag = IMAGE_ENCRYPT_EN;
+	ret = csi_efuse_set_bl2_img_encrypt_st(flag);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bl2_img_encrypt_st(&flag);
+	if (ret < 0)
+		return;
+	printf("after setting bl2 img flg: 0x%x\n", flag);
+}
+
+void csi_efuse_usr_brom_cct_test()
+{
+	brom_cct_st_t status;
+	int ret;
+
+	printf("csi_efuse_usr_brom_cct_test....\n");
+
+	ret = csi_efuse_get_usr_brom_cct_st(&status);
+	if (ret < 0)
+		return;
+	printf("before setting cct status: 0x%x\n", status);
+
+	ret = csi_efuse_dis_usr_brom_cct();
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_usr_brom_cct_st(&status);
+	if (ret < 0)
+		return;
+
+	printf("after setting cct status: 0x%x\n", status);
+}
+
+void csi_efuse_usr_brom_usb_fastboot_test()
+{
+	brom_usbboot_st_t status;
+	int ret;
+
+	ret = csi_efuse_get_usr_brom_usb_fastboot_st(&status);
+	if (ret < 0)
+		return;
+	printf("before setting fastboot status: 0x%x\n", status);
+
+	ret = csi_efuse_dis_usr_brom_usb_fastboot();
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_usr_brom_usb_fastboot_st(&status);
+	if (ret < 0)
+		return;
+
+	printf("after setting fastboot status: 0x%x\n", status);
+}
+
+void csi_efuse_bak_boot_index_test()
+{
+	int ret;
+	unsigned char index;
+
+	ret = csi_efuse_get_bak_boot_index(&index);
+	if (ret < 0)
+		return;
+
+	printf("\nbefore write bak boot index = %d\n", index);
+
+	index = 50;
+	ret = csi_efuse_set_bak_boot_index(index);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bak_boot_index(&index);
+	if (ret < 0)
+		return;
+
+	printf("\nafter write bak boot index = %d\n", index);
+}
+
+void csi_efuse_bak_boot_offset_test()
+{
+	int ret;
+	unsigned int offset;
+
+	ret = csi_efuse_get_bak_boot_offset(&offset);
+	if (ret < 0)
+		return;
+
+	printf("\nbefore write bak boot offset = %d\n", offset);
+
+	offset = 122;
+	ret = csi_efuse_set_bak_boot_offset(offset);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_bak_boot_offset(&offset);
+	if (ret < 0)
+		return;
+
+	printf("\nafter write bak boot offset = %d\n", offset);
+}
+
+void csi_efuse_boot_index_test()
+{
+	unsigned char index;
+	int ret;
+#if 1
+	ret = csi_efuse_set_boot_index(244);
+	if (ret < 0)
+		return;
+#endif
+	ret = csi_efuse_get_boot_index(&index);
+	if (ret < 0)
+		return;
+
+	printf("\nboot index = %d\n", index);
+}
+
+void csi_efuse_boot_offset_test()
+{
+	int ret;
+	unsigned int offset = 56;
+#if 1
+	ret = csi_efuse_set_boot_offset(offset);
+	if (ret < 0)
+		return;
+#endif
+	ret = csi_efuse_get_boot_offset(&offset);
+	if (ret < 0)
+		return;
+
+	printf("\noffset = 0x%x\n", offset);
+}
+
+void csi_efuse_user_dbg_mode_test()
+{
+	int ret;
+
+	efuse_dbg_type_t type = USR_CHIP_DBG;
+	efuse_dbg_mode_t mode = DBG_MODE_PWD_PROTECT;
+
+	ret = csi_efuse_set_user_dbg_mode(type, mode);
+	if (ret < 0)
+		return;
+
+	ret = csi_efuse_get_user_dbg_mode(type, &mode);
+	if (ret < 0)
+		return;
+
+	if (mode != DBG_MODE_ENABLE && mode != DBG_MODE_PWD_PROTECT &&
+			mode != DBG_MODE_DISABLE) {
+		printf("invalid debug mode in efuse\n");
+		return;
+	}
+
+	printf("\ndebug mode:%d\n", mode);
+}
+
+void efuse_chip_id_get_test()
+{
+	int ret;
+	unsigned char uid[20] = {};
+#if 0
+	ret = csi_efuse_write(0x50, &rw_uid, sizeof(unsigned int));
+	if (ret < 0)
+		return;
+#endif
+	ret = csi_efuse_get_chipid(&uid);
+	if (ret < 0)
+		printf("failed to read uid\n");
+
+	printf("\nuid: ");
+
+	for (int i = 0; i < 20; i++)
+		printf("%x", uid[i]);
+
+	printf("\n");
+}
+
+void csi_efuse_update_lc_rma_test()
+{
+	csi_efuse_update_lc_rma();
+}
+
+void csi_efuse_update_lc_rip_test()
+{
+	csi_efuse_update_lc_rip();
+}
+
+void csi_efuse_gmac_macaddr_test()
+{
+	int ret;
+	unsigned char mac0[6] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x00};
+	unsigned char mac1[6] = {0x00, 0x22, 0x33, 0x44, 0x66, 0x00};
+	unsigned char r_mac0[6] = {};
+	unsigned char r_mac1[6] = {};
+
+	ret = csi_efuse_set_gmac_macaddr(0, mac0);
+	if (ret < 0)
+		return;
+	ret = csi_efuse_get_gmac_macaddr(0, r_mac0);
+	if (ret < 0)
+		return;
+	printf("gmac mac0 address: %2x:%2x:%2x:%2x:%2x:%2x\n", r_mac0[0], r_mac0[1], r_mac0[2], r_mac0[3], r_mac0[4], r_mac0[5]);
+
+	ret = csi_efuse_set_gmac_macaddr(1, mac1);
+	if (ret < 0)
+		return;
+	ret = csi_efuse_get_gmac_macaddr(1, r_mac1);
+	if (ret < 0)
+		return;
+	printf("gmac mac0 address: %2x:%2x:%2x:%2x:%2x:%2x\n", r_mac1[0], r_mac1[1], r_mac1[2], r_mac1[3], r_mac1[4], r_mac1[5]);
+}
+
+int main()
+{
+#if 0
+	csi_efuse_bl4_img_encrypt_test();
+	csi_efuse_bl2_img_encrypt_test();
+	csi_efuse_bl3_img_encrypt_test();
+	csi_efuse_get_bl1_version_test();
+	csi_efuse_get_hash_challenge_test();
+	csi_efuse_get_secure_boot_st_test();
+#endif
+	csi_efuse_offset_test();
+#if 0
+	csi_efuse_usr_brom_cct_test();
+	csi_efuse_usr_brom_usb_fastboot_test();
+	csi_efuse_boot_index_test();
+	csi_efuse_boot_offset_test();
+	efuse_chip_id_get_test();
+	csi_efuse_get_bl1_version_test();
+	csi_efuse_get_bl2_version_test();
+	csi_efuse_get_secure_boot_st_test();
+	csi_efuse_get_hash_challenge_test();
+	csi_efuse_userdata_group_test();
+#endif
+
+#if 0
+	efuse_chip_id_get_test();
+	csi_efuse_user_dbg_mode_test();
+	csi_efuse_boot_offset_test();
+	csi_efuse_boot_index_test();
+	csi_efuse_bak_boot_offset_test();
+	csi_efuse_bak_boot_index_test();
+	csi_efuse_usr_brom_usb_fastboot_test();
+#endif
+
+#if 0
+	csi_efuse_usr_brom_cct_test();
+	printf("welcome to riscv world!!!\n");
+
+	csi_efuse_bl2_img_encrypt_test();
+	csi_efuse_bl3_img_encrypt_test();
+	csi_efuse_bl4_img_encrypt_test();
+	csi_efuse_get_bl1_version_test();
+	csi_efuse_get_bl2_version_test();
+	csi_efuse_get_secure_boot_st_test();
+	csi_efuse_get_hash_challenge_test();
+	csi_efuse_userdata_group_test();
+	csi_efuse_offset_test();
+#endif
+
+#if 0
+	csi_efuse_update_lc_rma_test();
+	csi_efuse_update_lc_rip_test();
+#endif
+#if 0
+	csi_efuse_gmac_macaddr_test();
+#endif
+	return 0;
+}

BIN
efuse-hal-lib/test/efuse_demo/light-efuse-test.o


BIN
efuse-hal-lib/test/output/efuse_demo


+ 548 - 0
emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/hmac_sha2.c

@@ -0,0 +1,548 @@
+/*
+ * HMAC-SHA-224/256/384/512 implementation
+ * Last update: 06/15/2005
+ * Issue date:  06/15/2005
+ *
+ * Since this code has been incorporated into a GPLv2 project, it is
+ * distributed under GPLv2 inside mmc-utils.  The original BSD license
+ * that the code was released under is included below for clarity.
+ *
+ * Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include "hmac_sha2.h"
+
+/* HMAC-SHA-224 functions */
+
+void hmac_sha224_init(hmac_sha224_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size)
+{
+    unsigned int fill;
+    unsigned int num;
+
+    const unsigned char *key_used;
+    unsigned char key_temp[SHA224_DIGEST_SIZE];
+    int i;
+
+    if (key_size == SHA224_BLOCK_SIZE) {
+        key_used = key;
+        num = SHA224_BLOCK_SIZE;
+    } else {
+        if (key_size > SHA224_BLOCK_SIZE){
+            num = SHA224_DIGEST_SIZE;
+            sha224(key, key_size, key_temp);
+            key_used = key_temp;
+        } else { /* key_size > SHA224_BLOCK_SIZE */
+            key_used = key;
+            num = key_size;
+        }
+        fill = SHA224_BLOCK_SIZE - num;
+
+        memset(ctx->block_ipad + num, 0x36, fill);
+        memset(ctx->block_opad + num, 0x5c, fill);
+    }
+
+    for (i = 0; i < (int) num; i++) {
+        ctx->block_ipad[i] = key_used[i] ^ 0x36;
+        ctx->block_opad[i] = key_used[i] ^ 0x5c;
+    }
+
+    sha224_init(&ctx->ctx_inside);
+    sha224_update(&ctx->ctx_inside, ctx->block_ipad, SHA224_BLOCK_SIZE);
+
+    sha224_init(&ctx->ctx_outside);
+    sha224_update(&ctx->ctx_outside, ctx->block_opad,
+                  SHA224_BLOCK_SIZE);
+
+    /* for hmac_reinit */
+    memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
+           sizeof(sha224_ctx));
+    memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
+           sizeof(sha224_ctx));
+}
+
+void hmac_sha224_reinit(hmac_sha224_ctx *ctx)
+{
+    memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
+           sizeof(sha224_ctx));
+    memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
+           sizeof(sha224_ctx));
+}
+
+void hmac_sha224_update(hmac_sha224_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len)
+{
+    sha224_update(&ctx->ctx_inside, message, message_len);
+}
+
+void hmac_sha224_final(hmac_sha224_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size)
+{
+    unsigned char digest_inside[SHA224_DIGEST_SIZE];
+    unsigned char mac_temp[SHA224_DIGEST_SIZE];
+
+    sha224_final(&ctx->ctx_inside, digest_inside);
+    sha224_update(&ctx->ctx_outside, digest_inside, SHA224_DIGEST_SIZE);
+    sha224_final(&ctx->ctx_outside, mac_temp);
+    memcpy(mac, mac_temp, mac_size);
+}
+
+void hmac_sha224(const unsigned char *key, unsigned int key_size,
+          const unsigned char *message, unsigned int message_len,
+          unsigned char *mac, unsigned mac_size)
+{
+    hmac_sha224_ctx ctx;
+
+    hmac_sha224_init(&ctx, key, key_size);
+    hmac_sha224_update(&ctx, message, message_len);
+    hmac_sha224_final(&ctx, mac, mac_size);
+}
+
+/* HMAC-SHA-256 functions */
+
+void hmac_sha256_init(hmac_sha256_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size)
+{
+    unsigned int fill;
+    unsigned int num;
+
+    const unsigned char *key_used;
+    unsigned char key_temp[SHA256_DIGEST_SIZE];
+    int i;
+
+    if (key_size == SHA256_BLOCK_SIZE) {
+        key_used = key;
+        num = SHA256_BLOCK_SIZE;
+    } else {
+        if (key_size > SHA256_BLOCK_SIZE){
+            num = SHA256_DIGEST_SIZE;
+            sha256(key, key_size, key_temp);
+            key_used = key_temp;
+        } else { /* key_size > SHA256_BLOCK_SIZE */
+            key_used = key;
+            num = key_size;
+        }
+        fill = SHA256_BLOCK_SIZE - num;
+
+        memset(ctx->block_ipad + num, 0x36, fill);
+        memset(ctx->block_opad + num, 0x5c, fill);
+    }
+
+    for (i = 0; i < (int) num; i++) {
+        ctx->block_ipad[i] = key_used[i] ^ 0x36;
+        ctx->block_opad[i] = key_used[i] ^ 0x5c;
+    }
+
+    sha256_init(&ctx->ctx_inside);
+    sha256_update(&ctx->ctx_inside, ctx->block_ipad, SHA256_BLOCK_SIZE);
+
+    sha256_init(&ctx->ctx_outside);
+    sha256_update(&ctx->ctx_outside, ctx->block_opad,
+                  SHA256_BLOCK_SIZE);
+
+    /* for hmac_reinit */
+    memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
+           sizeof(sha256_ctx));
+    memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
+           sizeof(sha256_ctx));
+}
+
+void hmac_sha256_reinit(hmac_sha256_ctx *ctx)
+{
+    memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
+           sizeof(sha256_ctx));
+    memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
+           sizeof(sha256_ctx));
+}
+
+void hmac_sha256_update(hmac_sha256_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len)
+{
+    sha256_update(&ctx->ctx_inside, message, message_len);
+}
+
+void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size)
+{
+    unsigned char digest_inside[SHA256_DIGEST_SIZE];
+    unsigned char mac_temp[SHA256_DIGEST_SIZE];
+
+    sha256_final(&ctx->ctx_inside, digest_inside);
+    sha256_update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_SIZE);
+    sha256_final(&ctx->ctx_outside, mac_temp);
+    memcpy(mac, mac_temp, mac_size);
+}
+
+void hmac_sha256(const unsigned char *key, unsigned int key_size,
+          const unsigned char *message, unsigned int message_len,
+          unsigned char *mac, unsigned mac_size)
+{
+    hmac_sha256_ctx ctx;
+
+    hmac_sha256_init(&ctx, key, key_size);
+    hmac_sha256_update(&ctx, message, message_len);
+    hmac_sha256_final(&ctx, mac, mac_size);
+}
+
+/* HMAC-SHA-384 functions */
+
+void hmac_sha384_init(hmac_sha384_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size)
+{
+    unsigned int fill;
+    unsigned int num;
+
+    const unsigned char *key_used;
+    unsigned char key_temp[SHA384_DIGEST_SIZE];
+    int i;
+
+    if (key_size == SHA384_BLOCK_SIZE) {
+        key_used = key;
+        num = SHA384_BLOCK_SIZE;
+    } else {
+        if (key_size > SHA384_BLOCK_SIZE){
+            num = SHA384_DIGEST_SIZE;
+            sha384(key, key_size, key_temp);
+            key_used = key_temp;
+        } else { /* key_size > SHA384_BLOCK_SIZE */
+            key_used = key;
+            num = key_size;
+        }
+        fill = SHA384_BLOCK_SIZE - num;
+
+        memset(ctx->block_ipad + num, 0x36, fill);
+        memset(ctx->block_opad + num, 0x5c, fill);
+    }
+
+    for (i = 0; i < (int) num; i++) {
+        ctx->block_ipad[i] = key_used[i] ^ 0x36;
+        ctx->block_opad[i] = key_used[i] ^ 0x5c;
+    }
+
+    sha384_init(&ctx->ctx_inside);
+    sha384_update(&ctx->ctx_inside, ctx->block_ipad, SHA384_BLOCK_SIZE);
+
+    sha384_init(&ctx->ctx_outside);
+    sha384_update(&ctx->ctx_outside, ctx->block_opad,
+                  SHA384_BLOCK_SIZE);
+
+    /* for hmac_reinit */
+    memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
+           sizeof(sha384_ctx));
+    memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
+           sizeof(sha384_ctx));
+}
+
+void hmac_sha384_reinit(hmac_sha384_ctx *ctx)
+{
+    memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
+           sizeof(sha384_ctx));
+    memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
+           sizeof(sha384_ctx));
+}
+
+void hmac_sha384_update(hmac_sha384_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len)
+{
+    sha384_update(&ctx->ctx_inside, message, message_len);
+}
+
+void hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size)
+{
+    unsigned char digest_inside[SHA384_DIGEST_SIZE];
+    unsigned char mac_temp[SHA384_DIGEST_SIZE];
+
+    sha384_final(&ctx->ctx_inside, digest_inside);
+    sha384_update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_SIZE);
+    sha384_final(&ctx->ctx_outside, mac_temp);
+    memcpy(mac, mac_temp, mac_size);
+}
+
+void hmac_sha384(const unsigned char *key, unsigned int key_size,
+          const unsigned char *message, unsigned int message_len,
+          unsigned char *mac, unsigned mac_size)
+{
+    hmac_sha384_ctx ctx;
+
+    hmac_sha384_init(&ctx, key, key_size);
+    hmac_sha384_update(&ctx, message, message_len);
+    hmac_sha384_final(&ctx, mac, mac_size);
+}
+
+/* HMAC-SHA-512 functions */
+
+void hmac_sha512_init(hmac_sha512_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size)
+{
+    unsigned int fill;
+    unsigned int num;
+
+    const unsigned char *key_used;
+    unsigned char key_temp[SHA512_DIGEST_SIZE];
+    int i;
+
+    if (key_size == SHA512_BLOCK_SIZE) {
+        key_used = key;
+        num = SHA512_BLOCK_SIZE;
+    } else {
+        if (key_size > SHA512_BLOCK_SIZE){
+            num = SHA512_DIGEST_SIZE;
+            sha512(key, key_size, key_temp);
+            key_used = key_temp;
+        } else { /* key_size > SHA512_BLOCK_SIZE */
+            key_used = key;
+            num = key_size;
+        }
+        fill = SHA512_BLOCK_SIZE - num;
+
+        memset(ctx->block_ipad + num, 0x36, fill);
+        memset(ctx->block_opad + num, 0x5c, fill);
+    }
+
+    for (i = 0; i < (int) num; i++) {
+        ctx->block_ipad[i] = key_used[i] ^ 0x36;
+        ctx->block_opad[i] = key_used[i] ^ 0x5c;
+    }
+
+    sha512_init(&ctx->ctx_inside);
+    sha512_update(&ctx->ctx_inside, ctx->block_ipad, SHA512_BLOCK_SIZE);
+
+    sha512_init(&ctx->ctx_outside);
+    sha512_update(&ctx->ctx_outside, ctx->block_opad,
+                  SHA512_BLOCK_SIZE);
+
+    /* for hmac_reinit */
+    memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
+           sizeof(sha512_ctx));
+    memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
+           sizeof(sha512_ctx));
+}
+
+void hmac_sha512_reinit(hmac_sha512_ctx *ctx)
+{
+    memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
+           sizeof(sha512_ctx));
+    memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
+           sizeof(sha512_ctx));
+}
+
+void hmac_sha512_update(hmac_sha512_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len)
+{
+    sha512_update(&ctx->ctx_inside, message, message_len);
+}
+
+void hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size)
+{
+    unsigned char digest_inside[SHA512_DIGEST_SIZE];
+    unsigned char mac_temp[SHA512_DIGEST_SIZE];
+
+    sha512_final(&ctx->ctx_inside, digest_inside);
+    sha512_update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_SIZE);
+    sha512_final(&ctx->ctx_outside, mac_temp);
+    memcpy(mac, mac_temp, mac_size);
+}
+
+void hmac_sha512(const unsigned char *key, unsigned int key_size,
+          const unsigned char *message, unsigned int message_len,
+          unsigned char *mac, unsigned mac_size)
+{
+    hmac_sha512_ctx ctx;
+
+    hmac_sha512_init(&ctx, key, key_size);
+    hmac_sha512_update(&ctx, message, message_len);
+    hmac_sha512_final(&ctx, mac, mac_size);
+}
+
+#ifdef TEST_VECTORS
+
+/* IETF Validation tests */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void test(const char *vector, unsigned char *digest,
+          unsigned int digest_size)
+{
+    char output[2 * SHA512_DIGEST_SIZE + 1];
+    int i;
+
+    output[2 * digest_size] = '\0';
+
+    for (i = 0; i < (int) digest_size ; i++) {
+       sprintf(output + 2*i, "%02x", digest[i]);
+    }
+
+    printf("H: %s\n", output);
+    if (strcmp(vector, output)) {
+        fprintf(stderr, "Test failed.\n");
+        exit(1);
+    }
+}
+
+int main(void)
+{
+    static const char *vectors[] =
+    {
+        /* HMAC-SHA-224 */
+        "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22",
+        "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44",
+        "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea",
+        "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a",
+        "0e2aea68a90c8d37c988bcdb9fca6fa8",
+        "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e",
+        "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1",
+        /* HMAC-SHA-256 */
+        "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
+        "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
+        "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
+        "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
+        "a3b6167473100ee06e0c796c2955552b",
+        "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
+        "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
+        /* HMAC-SHA-384 */
+        "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c"
+        "faea9ea9076ede7f4af152e8b2fa9cb6",
+        "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e"
+        "8e2240ca5e69e2c78b3239ecfab21649",
+        "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b"
+        "2a5ab39dc13814b94e3ab6e101a34f27",
+        "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e"
+        "6801dd23c4a7d679ccf8a386c674cffb",
+        "3abf34c3503b2a23a46efc619baef897",
+        "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6"
+        "0c2ef6ab4030fe8296248df163f44952",
+        "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5"
+        "a678cc31e799176d3860e6110c46523e",
+        /* HMAC-SHA-512 */
+        "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
+        "daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854",
+        "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
+        "9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737",
+        "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
+        "bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
+        "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
+        "a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd",
+        "415fad6271580a531d4179bc891d87a6",
+        "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
+        "6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598",
+        "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
+        "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"
+    };
+
+    static char *messages[] =
+    {
+        "Hi There",
+        "what do ya want for nothing?",
+        NULL,
+        NULL,
+        "Test With Truncation",
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+        "This is a test using a larger than block-size key "
+        "and a larger than block-size data. The key needs"
+        " to be hashed before being used by the HMAC algorithm."
+    };
+
+    unsigned char mac[SHA512_DIGEST_SIZE];
+    unsigned char *keys[7];
+    unsigned int keys_len[7] = {20, 4, 20, 25, 20, 131, 131};
+    unsigned int messages2and3_len = 50;
+    unsigned int mac_224_size, mac_256_size, mac_384_size, mac_512_size;
+    int i;
+
+    for (i = 0; i < 7; i++) {
+        keys[i] = malloc(keys_len[i]);
+        if (keys[i] == NULL) {
+            fprintf(stderr, "Can't allocate memory\n");
+            return 1;
+        }
+    }
+
+    memset(keys[0], 0x0b, keys_len[0]);
+    strcpy((char *) keys[1], "Jefe");
+    memset(keys[2], 0xaa, keys_len[2]);
+    for (i = 0; i < (int) keys_len[3]; i++)
+        keys[3][i] = (unsigned char) i + 1;
+    memset(keys[4], 0x0c, keys_len[4]);
+    memset(keys[5], 0xaa, keys_len[5]);
+    memset(keys[6], 0xaa, keys_len[6]);
+
+    messages[2] = malloc(messages2and3_len + 1);
+    messages[3] = malloc(messages2and3_len + 1);
+
+    if (messages[2] == NULL || messages[3] == NULL) {
+        fprintf(stderr, "Can't allocate memory\n");
+        return 1;
+    }
+
+    messages[2][messages2and3_len] = '\0';
+    messages[3][messages2and3_len] = '\0';
+
+    memset(messages[2], 0xdd, messages2and3_len);
+    memset(messages[3], 0xcd, messages2and3_len);
+
+    printf("HMAC-SHA-2 IETF Validation tests\n\n");
+
+    for (i = 0; i < 7; i++) {
+        if (i != 4) {
+            mac_224_size = SHA224_DIGEST_SIZE;
+            mac_256_size = SHA256_DIGEST_SIZE;
+            mac_384_size = SHA384_DIGEST_SIZE;
+            mac_512_size = SHA512_DIGEST_SIZE;
+        } else {
+            mac_224_size = 128 / 8; mac_256_size = 128 / 8;
+            mac_384_size = 128 / 8; mac_512_size = 128 / 8;
+        }
+
+        printf("Test %d:\n", i + 1);
+
+        hmac_sha224(keys[i], keys_len[i], (unsigned char *) messages[i],
+                    strlen(messages[i]), mac, mac_224_size);
+        test(vectors[i], mac, mac_224_size);
+        hmac_sha256(keys[i], keys_len[i], (unsigned char *) messages[i],
+                    strlen(messages[i]), mac, mac_256_size);
+        test(vectors[7 + i], mac, mac_256_size);
+        hmac_sha384(keys[i], keys_len[i], (unsigned char *) messages[i],
+                    strlen(messages[i]), mac, mac_384_size);
+        test(vectors[14 + i], mac, mac_384_size);
+        hmac_sha512(keys[i], keys_len[i], (unsigned char *) messages[i],
+                    strlen(messages[i]), mac, mac_512_size);
+        test(vectors[21 + i], mac, mac_512_size);
+    }
+
+    printf("All tests passed.\n");
+
+    return 0;
+}
+
+#endif /* TEST_VECTORS */
+

+ 144 - 0
emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/hmac_sha2.h

@@ -0,0 +1,144 @@
+/*
+ * HMAC-SHA-224/256/384/512 implementation
+ * Last update: 06/15/2005
+ * Issue date:  06/15/2005
+ *
+ * Since this code has been incorporated into a GPLv2 project, it is
+ * distributed under GPLv2 inside mmc-utils.  The original BSD license
+ * that the code was released under is included below for clarity.
+ *
+ * Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HMAC_SHA2_H
+#define HMAC_SHA2_H
+
+#include "sha2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    sha224_ctx ctx_inside;
+    sha224_ctx ctx_outside;
+
+    /* for hmac_reinit */
+    sha224_ctx ctx_inside_reinit;
+    sha224_ctx ctx_outside_reinit;
+
+    unsigned char block_ipad[SHA224_BLOCK_SIZE];
+    unsigned char block_opad[SHA224_BLOCK_SIZE];
+} hmac_sha224_ctx;
+
+typedef struct {
+    sha256_ctx ctx_inside;
+    sha256_ctx ctx_outside;
+
+    /* for hmac_reinit */
+    sha256_ctx ctx_inside_reinit;
+    sha256_ctx ctx_outside_reinit;
+
+    unsigned char block_ipad[SHA256_BLOCK_SIZE];
+    unsigned char block_opad[SHA256_BLOCK_SIZE];
+} hmac_sha256_ctx;
+
+typedef struct {
+    sha384_ctx ctx_inside;
+    sha384_ctx ctx_outside;
+
+    /* for hmac_reinit */
+    sha384_ctx ctx_inside_reinit;
+    sha384_ctx ctx_outside_reinit;
+
+    unsigned char block_ipad[SHA384_BLOCK_SIZE];
+    unsigned char block_opad[SHA384_BLOCK_SIZE];
+} hmac_sha384_ctx;
+
+typedef struct {
+    sha512_ctx ctx_inside;
+    sha512_ctx ctx_outside;
+
+    /* for hmac_reinit */
+    sha512_ctx ctx_inside_reinit;
+    sha512_ctx ctx_outside_reinit;
+
+    unsigned char block_ipad[SHA512_BLOCK_SIZE];
+    unsigned char block_opad[SHA512_BLOCK_SIZE];
+} hmac_sha512_ctx;
+
+void hmac_sha224_init(hmac_sha224_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size);
+void hmac_sha224_reinit(hmac_sha224_ctx *ctx);
+void hmac_sha224_update(hmac_sha224_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len);
+void hmac_sha224_final(hmac_sha224_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size);
+void hmac_sha224(const unsigned char *key, unsigned int key_size,
+                 const unsigned char *message, unsigned int message_len,
+                 unsigned char *mac, unsigned mac_size);
+
+void hmac_sha256_init(hmac_sha256_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size);
+void hmac_sha256_reinit(hmac_sha256_ctx *ctx);
+void hmac_sha256_update(hmac_sha256_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len);
+void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size);
+void hmac_sha256(const unsigned char *key, unsigned int key_size,
+                 const unsigned char *message, unsigned int message_len,
+                 unsigned char *mac, unsigned mac_size);
+
+void hmac_sha384_init(hmac_sha384_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size);
+void hmac_sha384_reinit(hmac_sha384_ctx *ctx);
+void hmac_sha384_update(hmac_sha384_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len);
+void hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size);
+void hmac_sha384(const unsigned char *key, unsigned int key_size,
+                 const unsigned char *message, unsigned int message_len,
+                 unsigned char *mac, unsigned mac_size);
+
+void hmac_sha512_init(hmac_sha512_ctx *ctx, const unsigned char *key,
+                      unsigned int key_size);
+void hmac_sha512_reinit(hmac_sha512_ctx *ctx);
+void hmac_sha512_update(hmac_sha512_ctx *ctx, const unsigned char *message,
+                        unsigned int message_len);
+void hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *mac,
+                       unsigned int mac_size);
+void hmac_sha512(const unsigned char *key, unsigned int key_size,
+                 const unsigned char *message, unsigned int message_len,
+                 unsigned char *mac, unsigned mac_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !HMAC_SHA2_H */
+

+ 953 - 0
emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/sha2.c

@@ -0,0 +1,953 @@
+/*
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 02/02/2007
+ * Issue date:  04/30/2005
+ *
+ * Since this code has been incorporated into a GPLv2 project, it is
+ * distributed under GPLv2 inside mmc-utils.  The original BSD license
+ * that the code was released under is included below for clarity.
+ *
+ * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#define UNROLL_LOOPS /* Enable loops unrolling */
+#endif
+
+#include <string.h>
+
+#include "sha2.h"
+
+#define SHFR(x, n)    (x >> n)
+#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
+#define ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
+#define CH(x, y, z)  ((x & y) ^ (~x & z))
+#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
+#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
+
+#define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
+#define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
+#define SHA512_F3(x) (ROTR(x,  1) ^ ROTR(x,  8) ^ SHFR(x,  7))
+#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x,  6))
+
+#define UNPACK32(x, str)                      \
+{                                             \
+    *((str) + 3) = (uint8) ((x)      );       \
+    *((str) + 2) = (uint8) ((x) >>  8);       \
+    *((str) + 1) = (uint8) ((x) >> 16);       \
+    *((str) + 0) = (uint8) ((x) >> 24);       \
+}
+
+#define PACK32(str, x)                        \
+{                                             \
+    *(x) =   ((uint32) *((str) + 3)      )    \
+           | ((uint32) *((str) + 2) <<  8)    \
+           | ((uint32) *((str) + 1) << 16)    \
+           | ((uint32) *((str) + 0) << 24);   \
+}
+
+#define UNPACK64(x, str)                      \
+{                                             \
+    *((str) + 7) = (uint8) ((x)      );       \
+    *((str) + 6) = (uint8) ((x) >>  8);       \
+    *((str) + 5) = (uint8) ((x) >> 16);       \
+    *((str) + 4) = (uint8) ((x) >> 24);       \
+    *((str) + 3) = (uint8) ((x) >> 32);       \
+    *((str) + 2) = (uint8) ((x) >> 40);       \
+    *((str) + 1) = (uint8) ((x) >> 48);       \
+    *((str) + 0) = (uint8) ((x) >> 56);       \
+}
+
+#define PACK64(str, x)                        \
+{                                             \
+    *(x) =   ((uint64) *((str) + 7)      )    \
+           | ((uint64) *((str) + 6) <<  8)    \
+           | ((uint64) *((str) + 5) << 16)    \
+           | ((uint64) *((str) + 4) << 24)    \
+           | ((uint64) *((str) + 3) << 32)    \
+           | ((uint64) *((str) + 2) << 40)    \
+           | ((uint64) *((str) + 1) << 48)    \
+           | ((uint64) *((str) + 0) << 56);   \
+}
+
+/* Macros used for loops unrolling */
+
+#define SHA256_SCR(i)                         \
+{                                             \
+    w[i] =  SHA256_F4(w[i -  2]) + w[i -  7]  \
+          + SHA256_F3(w[i - 15]) + w[i - 16]; \
+}
+
+#define SHA512_SCR(i)                         \
+{                                             \
+    w[i] =  SHA512_F4(w[i -  2]) + w[i -  7]  \
+          + SHA512_F3(w[i - 15]) + w[i - 16]; \
+}
+
+#define SHA256_EXP(a, b, c, d, e, f, g, h, j)               \
+{                                                           \
+    t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+         + sha256_k[j] + w[j];                              \
+    t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);       \
+    wv[d] += t1;                                            \
+    wv[h] = t1 + t2;                                        \
+}
+
+#define SHA512_EXP(a, b, c, d, e, f, g ,h, j)               \
+{                                                           \
+    t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+         + sha512_k[j] + w[j];                              \
+    t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);       \
+    wv[d] += t1;                                            \
+    wv[h] = t1 + t2;                                        \
+}
+
+uint32 sha224_h0[8] =
+            {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
+
+uint32 sha256_h0[8] =
+            {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+uint64 sha384_h0[8] =
+            {0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
+             0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
+             0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+             0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
+
+uint64 sha512_h0[8] =
+            {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+             0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+             0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+             0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
+
+uint32 sha256_k[64] =
+            {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
+
+uint64 sha512_k[80] =
+            {0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+             0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+             0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+             0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+             0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+             0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+             0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+             0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+             0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+             0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+             0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+             0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+             0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+             0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+             0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+             0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+             0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+             0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+             0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+             0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+             0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+             0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+             0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+             0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+             0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+             0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+             0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+             0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+             0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+             0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+             0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+             0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+             0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+             0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+             0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+             0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+             0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+             0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+             0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+             0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
+
+/* SHA-256 functions */
+
+void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
+                   unsigned int block_nb)
+{
+    uint32 w[64];
+    uint32 wv[8];
+    uint32 t1, t2;
+    const unsigned char *sub_block;
+    int i;
+
+#ifndef UNROLL_LOOPS
+    int j;
+#endif
+
+    for (i = 0; i < (int) block_nb; i++) {
+        sub_block = message + (i << 6);
+
+#ifndef UNROLL_LOOPS
+        for (j = 0; j < 16; j++) {
+            PACK32(&sub_block[j << 2], &w[j]);
+        }
+
+        for (j = 16; j < 64; j++) {
+            SHA256_SCR(j);
+        }
+
+        for (j = 0; j < 8; j++) {
+            wv[j] = ctx->h[j];
+        }
+
+        for (j = 0; j < 64; j++) {
+            t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+                + sha256_k[j] + w[j];
+            t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
+            wv[7] = wv[6];
+            wv[6] = wv[5];
+            wv[5] = wv[4];
+            wv[4] = wv[3] + t1;
+            wv[3] = wv[2];
+            wv[2] = wv[1];
+            wv[1] = wv[0];
+            wv[0] = t1 + t2;
+        }
+
+        for (j = 0; j < 8; j++) {
+            ctx->h[j] += wv[j];
+        }
+#else
+        PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]);
+        PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]);
+        PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]);
+        PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]);
+        PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]);
+        PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]);
+        PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]);
+        PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]);
+
+        SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19);
+        SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23);
+        SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27);
+        SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31);
+        SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35);
+        SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39);
+        SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43);
+        SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47);
+        SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51);
+        SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55);
+        SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59);
+        SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63);
+
+        wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
+        wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
+        wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
+        wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
+
+        SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1);
+        SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3);
+        SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5);
+        SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7);
+        SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9);
+        SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11);
+        SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13);
+        SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15);
+        SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17);
+        SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19);
+        SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21);
+        SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23);
+        SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25);
+        SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27);
+        SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29);
+        SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31);
+        SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33);
+        SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35);
+        SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37);
+        SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39);
+        SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41);
+        SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43);
+        SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45);
+        SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47);
+        SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49);
+        SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51);
+        SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53);
+        SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55);
+        SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57);
+        SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59);
+        SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61);
+        SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63);
+
+        ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
+        ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
+        ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
+        ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
+#endif /* !UNROLL_LOOPS */
+    }
+}
+
+void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
+{
+    sha256_ctx ctx;
+
+    sha256_init(&ctx);
+    sha256_update(&ctx, message, len);
+    sha256_final(&ctx, digest);
+}
+
+void sha256_init(sha256_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+    int i;
+    for (i = 0; i < 8; i++) {
+        ctx->h[i] = sha256_h0[i];
+    }
+#else
+    ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1];
+    ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3];
+    ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5];
+    ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7];
+#endif /* !UNROLL_LOOPS */
+
+    ctx->len = 0;
+    ctx->tot_len = 0;
+}
+
+void sha256_update(sha256_ctx *ctx, const unsigned char *message,
+                   unsigned int len)
+{
+    unsigned int block_nb;
+    unsigned int new_len, rem_len, tmp_len;
+    const unsigned char *shifted_message;
+
+    tmp_len = SHA256_BLOCK_SIZE - ctx->len;
+    rem_len = len < tmp_len ? len : tmp_len;
+
+    memcpy(&ctx->block[ctx->len], message, rem_len);
+
+    if (ctx->len + len < SHA256_BLOCK_SIZE) {
+        ctx->len += len;
+        return;
+    }
+
+    new_len = len - rem_len;
+    block_nb = new_len / SHA256_BLOCK_SIZE;
+
+    shifted_message = message + rem_len;
+
+    sha256_transf(ctx, ctx->block, 1);
+    sha256_transf(ctx, shifted_message, block_nb);
+
+    rem_len = new_len % SHA256_BLOCK_SIZE;
+
+    memcpy(ctx->block, &shifted_message[block_nb << 6],
+           rem_len);
+
+    ctx->len = rem_len;
+    ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void sha256_final(sha256_ctx *ctx, unsigned char *digest)
+{
+    unsigned int block_nb;
+    unsigned int pm_len;
+    unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+    int i;
+#endif
+
+    block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
+                     < (ctx->len % SHA256_BLOCK_SIZE)));
+
+    len_b = (ctx->tot_len + ctx->len) << 3;
+    pm_len = block_nb << 6;
+
+    memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+    ctx->block[ctx->len] = 0x80;
+    UNPACK32(len_b, ctx->block + pm_len - 4);
+
+    sha256_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+    for (i = 0 ; i < 8; i++) {
+        UNPACK32(ctx->h[i], &digest[i << 2]);
+    }
+#else
+   UNPACK32(ctx->h[0], &digest[ 0]);
+   UNPACK32(ctx->h[1], &digest[ 4]);
+   UNPACK32(ctx->h[2], &digest[ 8]);
+   UNPACK32(ctx->h[3], &digest[12]);
+   UNPACK32(ctx->h[4], &digest[16]);
+   UNPACK32(ctx->h[5], &digest[20]);
+   UNPACK32(ctx->h[6], &digest[24]);
+   UNPACK32(ctx->h[7], &digest[28]);
+#endif /* !UNROLL_LOOPS */
+}
+
+/* SHA-512 functions */
+
+void sha512_transf(sha512_ctx *ctx, const unsigned char *message,
+                   unsigned int block_nb)
+{
+    uint64 w[80];
+    uint64 wv[8];
+    uint64 t1, t2;
+    const unsigned char *sub_block;
+    int i, j;
+
+    for (i = 0; i < (int) block_nb; i++) {
+        sub_block = message + (i << 7);
+
+#ifndef UNROLL_LOOPS
+        for (j = 0; j < 16; j++) {
+            PACK64(&sub_block[j << 3], &w[j]);
+        }
+
+        for (j = 16; j < 80; j++) {
+            SHA512_SCR(j);
+        }
+
+        for (j = 0; j < 8; j++) {
+            wv[j] = ctx->h[j];
+        }
+
+        for (j = 0; j < 80; j++) {
+            t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+                + sha512_k[j] + w[j];
+            t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
+            wv[7] = wv[6];
+            wv[6] = wv[5];
+            wv[5] = wv[4];
+            wv[4] = wv[3] + t1;
+            wv[3] = wv[2];
+            wv[2] = wv[1];
+            wv[1] = wv[0];
+            wv[0] = t1 + t2;
+        }
+
+        for (j = 0; j < 8; j++) {
+            ctx->h[j] += wv[j];
+        }
+#else
+        PACK64(&sub_block[  0], &w[ 0]); PACK64(&sub_block[  8], &w[ 1]);
+        PACK64(&sub_block[ 16], &w[ 2]); PACK64(&sub_block[ 24], &w[ 3]);
+        PACK64(&sub_block[ 32], &w[ 4]); PACK64(&sub_block[ 40], &w[ 5]);
+        PACK64(&sub_block[ 48], &w[ 6]); PACK64(&sub_block[ 56], &w[ 7]);
+        PACK64(&sub_block[ 64], &w[ 8]); PACK64(&sub_block[ 72], &w[ 9]);
+        PACK64(&sub_block[ 80], &w[10]); PACK64(&sub_block[ 88], &w[11]);
+        PACK64(&sub_block[ 96], &w[12]); PACK64(&sub_block[104], &w[13]);
+        PACK64(&sub_block[112], &w[14]); PACK64(&sub_block[120], &w[15]);
+
+        SHA512_SCR(16); SHA512_SCR(17); SHA512_SCR(18); SHA512_SCR(19);
+        SHA512_SCR(20); SHA512_SCR(21); SHA512_SCR(22); SHA512_SCR(23);
+        SHA512_SCR(24); SHA512_SCR(25); SHA512_SCR(26); SHA512_SCR(27);
+        SHA512_SCR(28); SHA512_SCR(29); SHA512_SCR(30); SHA512_SCR(31);
+        SHA512_SCR(32); SHA512_SCR(33); SHA512_SCR(34); SHA512_SCR(35);
+        SHA512_SCR(36); SHA512_SCR(37); SHA512_SCR(38); SHA512_SCR(39);
+        SHA512_SCR(40); SHA512_SCR(41); SHA512_SCR(42); SHA512_SCR(43);
+        SHA512_SCR(44); SHA512_SCR(45); SHA512_SCR(46); SHA512_SCR(47);
+        SHA512_SCR(48); SHA512_SCR(49); SHA512_SCR(50); SHA512_SCR(51);
+        SHA512_SCR(52); SHA512_SCR(53); SHA512_SCR(54); SHA512_SCR(55);
+        SHA512_SCR(56); SHA512_SCR(57); SHA512_SCR(58); SHA512_SCR(59);
+        SHA512_SCR(60); SHA512_SCR(61); SHA512_SCR(62); SHA512_SCR(63);
+        SHA512_SCR(64); SHA512_SCR(65); SHA512_SCR(66); SHA512_SCR(67);
+        SHA512_SCR(68); SHA512_SCR(69); SHA512_SCR(70); SHA512_SCR(71);
+        SHA512_SCR(72); SHA512_SCR(73); SHA512_SCR(74); SHA512_SCR(75);
+        SHA512_SCR(76); SHA512_SCR(77); SHA512_SCR(78); SHA512_SCR(79);
+
+        wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
+        wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
+        wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
+        wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
+
+        j = 0;
+
+        do {
+            SHA512_EXP(0,1,2,3,4,5,6,7,j); j++;
+            SHA512_EXP(7,0,1,2,3,4,5,6,j); j++;
+            SHA512_EXP(6,7,0,1,2,3,4,5,j); j++;
+            SHA512_EXP(5,6,7,0,1,2,3,4,j); j++;
+            SHA512_EXP(4,5,6,7,0,1,2,3,j); j++;
+            SHA512_EXP(3,4,5,6,7,0,1,2,j); j++;
+            SHA512_EXP(2,3,4,5,6,7,0,1,j); j++;
+            SHA512_EXP(1,2,3,4,5,6,7,0,j); j++;
+        } while (j < 80);
+
+        ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
+        ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
+        ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
+        ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
+#endif /* !UNROLL_LOOPS */
+    }
+}
+
+void sha512(const unsigned char *message, unsigned int len,
+            unsigned char *digest)
+{
+    sha512_ctx ctx;
+
+    sha512_init(&ctx);
+    sha512_update(&ctx, message, len);
+    sha512_final(&ctx, digest);
+}
+
+void sha512_init(sha512_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+    int i;
+    for (i = 0; i < 8; i++) {
+        ctx->h[i] = sha512_h0[i];
+    }
+#else
+    ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1];
+    ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3];
+    ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5];
+    ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7];
+#endif /* !UNROLL_LOOPS */
+
+    ctx->len = 0;
+    ctx->tot_len = 0;
+}
+
+void sha512_update(sha512_ctx *ctx, const unsigned char *message,
+                   unsigned int len)
+{
+    unsigned int block_nb;
+    unsigned int new_len, rem_len, tmp_len;
+    const unsigned char *shifted_message;
+
+    tmp_len = SHA512_BLOCK_SIZE - ctx->len;
+    rem_len = len < tmp_len ? len : tmp_len;
+
+    memcpy(&ctx->block[ctx->len], message, rem_len);
+
+    if (ctx->len + len < SHA512_BLOCK_SIZE) {
+        ctx->len += len;
+        return;
+    }
+
+    new_len = len - rem_len;
+    block_nb = new_len / SHA512_BLOCK_SIZE;
+
+    shifted_message = message + rem_len;
+
+    sha512_transf(ctx, ctx->block, 1);
+    sha512_transf(ctx, shifted_message, block_nb);
+
+    rem_len = new_len % SHA512_BLOCK_SIZE;
+
+    memcpy(ctx->block, &shifted_message[block_nb << 7],
+           rem_len);
+
+    ctx->len = rem_len;
+    ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void sha512_final(sha512_ctx *ctx, unsigned char *digest)
+{
+    unsigned int block_nb;
+    unsigned int pm_len;
+    unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+    int i;
+#endif
+
+    block_nb = 1 + ((SHA512_BLOCK_SIZE - 17)
+                     < (ctx->len % SHA512_BLOCK_SIZE));
+
+    len_b = (ctx->tot_len + ctx->len) << 3;
+    pm_len = block_nb << 7;
+
+    memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+    ctx->block[ctx->len] = 0x80;
+    UNPACK32(len_b, ctx->block + pm_len - 4);
+
+    sha512_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+    for (i = 0 ; i < 8; i++) {
+        UNPACK64(ctx->h[i], &digest[i << 3]);
+    }
+#else
+    UNPACK64(ctx->h[0], &digest[ 0]);
+    UNPACK64(ctx->h[1], &digest[ 8]);
+    UNPACK64(ctx->h[2], &digest[16]);
+    UNPACK64(ctx->h[3], &digest[24]);
+    UNPACK64(ctx->h[4], &digest[32]);
+    UNPACK64(ctx->h[5], &digest[40]);
+    UNPACK64(ctx->h[6], &digest[48]);
+    UNPACK64(ctx->h[7], &digest[56]);
+#endif /* !UNROLL_LOOPS */
+}
+
+/* SHA-384 functions */
+
+void sha384(const unsigned char *message, unsigned int len,
+            unsigned char *digest)
+{
+    sha384_ctx ctx;
+
+    sha384_init(&ctx);
+    sha384_update(&ctx, message, len);
+    sha384_final(&ctx, digest);
+}
+
+void sha384_init(sha384_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+    int i;
+    for (i = 0; i < 8; i++) {
+        ctx->h[i] = sha384_h0[i];
+    }
+#else
+    ctx->h[0] = sha384_h0[0]; ctx->h[1] = sha384_h0[1];
+    ctx->h[2] = sha384_h0[2]; ctx->h[3] = sha384_h0[3];
+    ctx->h[4] = sha384_h0[4]; ctx->h[5] = sha384_h0[5];
+    ctx->h[6] = sha384_h0[6]; ctx->h[7] = sha384_h0[7];
+#endif /* !UNROLL_LOOPS */
+
+    ctx->len = 0;
+    ctx->tot_len = 0;
+}
+
+void sha384_update(sha384_ctx *ctx, const unsigned char *message,
+                   unsigned int len)
+{
+    unsigned int block_nb;
+    unsigned int new_len, rem_len, tmp_len;
+    const unsigned char *shifted_message;
+
+    tmp_len = SHA384_BLOCK_SIZE - ctx->len;
+    rem_len = len < tmp_len ? len : tmp_len;
+
+    memcpy(&ctx->block[ctx->len], message, rem_len);
+
+    if (ctx->len + len < SHA384_BLOCK_SIZE) {
+        ctx->len += len;
+        return;
+    }
+
+    new_len = len - rem_len;
+    block_nb = new_len / SHA384_BLOCK_SIZE;
+
+    shifted_message = message + rem_len;
+
+    sha512_transf(ctx, ctx->block, 1);
+    sha512_transf(ctx, shifted_message, block_nb);
+
+    rem_len = new_len % SHA384_BLOCK_SIZE;
+
+    memcpy(ctx->block, &shifted_message[block_nb << 7],
+           rem_len);
+
+    ctx->len = rem_len;
+    ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void sha384_final(sha384_ctx *ctx, unsigned char *digest)
+{
+    unsigned int block_nb;
+    unsigned int pm_len;
+    unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+    int i;
+#endif
+
+    block_nb = (1 + ((SHA384_BLOCK_SIZE - 17)
+                     < (ctx->len % SHA384_BLOCK_SIZE)));
+
+    len_b = (ctx->tot_len + ctx->len) << 3;
+    pm_len = block_nb << 7;
+
+    memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+    ctx->block[ctx->len] = 0x80;
+    UNPACK32(len_b, ctx->block + pm_len - 4);
+
+    sha512_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+    for (i = 0 ; i < 6; i++) {
+        UNPACK64(ctx->h[i], &digest[i << 3]);
+    }
+#else
+    UNPACK64(ctx->h[0], &digest[ 0]);
+    UNPACK64(ctx->h[1], &digest[ 8]);
+    UNPACK64(ctx->h[2], &digest[16]);
+    UNPACK64(ctx->h[3], &digest[24]);
+    UNPACK64(ctx->h[4], &digest[32]);
+    UNPACK64(ctx->h[5], &digest[40]);
+#endif /* !UNROLL_LOOPS */
+}
+
+/* SHA-224 functions */
+
+void sha224(const unsigned char *message, unsigned int len,
+            unsigned char *digest)
+{
+    sha224_ctx ctx;
+
+    sha224_init(&ctx);
+    sha224_update(&ctx, message, len);
+    sha224_final(&ctx, digest);
+}
+
+void sha224_init(sha224_ctx *ctx)
+{
+#ifndef UNROLL_LOOPS
+    int i;
+    for (i = 0; i < 8; i++) {
+        ctx->h[i] = sha224_h0[i];
+    }
+#else
+    ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1];
+    ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3];
+    ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5];
+    ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7];
+#endif /* !UNROLL_LOOPS */
+
+    ctx->len = 0;
+    ctx->tot_len = 0;
+}
+
+void sha224_update(sha224_ctx *ctx, const unsigned char *message,
+                   unsigned int len)
+{
+    unsigned int block_nb;
+    unsigned int new_len, rem_len, tmp_len;
+    const unsigned char *shifted_message;
+
+    tmp_len = SHA224_BLOCK_SIZE - ctx->len;
+    rem_len = len < tmp_len ? len : tmp_len;
+
+    memcpy(&ctx->block[ctx->len], message, rem_len);
+
+    if (ctx->len + len < SHA224_BLOCK_SIZE) {
+        ctx->len += len;
+        return;
+    }
+
+    new_len = len - rem_len;
+    block_nb = new_len / SHA224_BLOCK_SIZE;
+
+    shifted_message = message + rem_len;
+
+    sha256_transf(ctx, ctx->block, 1);
+    sha256_transf(ctx, shifted_message, block_nb);
+
+    rem_len = new_len % SHA224_BLOCK_SIZE;
+
+    memcpy(ctx->block, &shifted_message[block_nb << 6],
+           rem_len);
+
+    ctx->len = rem_len;
+    ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void sha224_final(sha224_ctx *ctx, unsigned char *digest)
+{
+    unsigned int block_nb;
+    unsigned int pm_len;
+    unsigned int len_b;
+
+#ifndef UNROLL_LOOPS
+    int i;
+#endif
+
+    block_nb = (1 + ((SHA224_BLOCK_SIZE - 9)
+                     < (ctx->len % SHA224_BLOCK_SIZE)));
+
+    len_b = (ctx->tot_len + ctx->len) << 3;
+    pm_len = block_nb << 6;
+
+    memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+    ctx->block[ctx->len] = 0x80;
+    UNPACK32(len_b, ctx->block + pm_len - 4);
+
+    sha256_transf(ctx, ctx->block, block_nb);
+
+#ifndef UNROLL_LOOPS
+    for (i = 0 ; i < 7; i++) {
+        UNPACK32(ctx->h[i], &digest[i << 2]);
+    }
+#else
+   UNPACK32(ctx->h[0], &digest[ 0]);
+   UNPACK32(ctx->h[1], &digest[ 4]);
+   UNPACK32(ctx->h[2], &digest[ 8]);
+   UNPACK32(ctx->h[3], &digest[12]);
+   UNPACK32(ctx->h[4], &digest[16]);
+   UNPACK32(ctx->h[5], &digest[20]);
+   UNPACK32(ctx->h[6], &digest[24]);
+#endif /* !UNROLL_LOOPS */
+}
+
+#ifdef TEST_VECTORS
+
+/* FIPS 180-2 Validation tests */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void test(const char *vector, unsigned char *digest,
+          unsigned int digest_size)
+{
+    char output[2 * SHA512_DIGEST_SIZE + 1];
+    int i;
+
+    output[2 * digest_size] = '\0';
+
+    for (i = 0; i < (int) digest_size ; i++) {
+       sprintf(output + 2 * i, "%02x", digest[i]);
+    }
+
+    printf("H: %s\n", output);
+    if (strcmp(vector, output)) {
+        fprintf(stderr, "Test failed.\n");
+        exit(EXIT_FAILURE);
+    }
+}
+
+int main(void)
+{
+    static const char *vectors[4][3] =
+    {   /* SHA-224 */
+        {
+        "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+        "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
+        "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67",
+        },
+        /* SHA-256 */
+        {
+        "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+        "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+        "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
+        },
+        /* SHA-384 */
+        {
+        "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
+        "8086072ba1e7cc2358baeca134c825a7",
+        "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
+        "fcc7c71a557e2db966c3e9fa91746039",
+        "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"
+        "07b8b3dc38ecc4ebae97ddd87f3d8985",
+        },
+        /* SHA-512 */
+        {
+        "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+        "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+        "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+        "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
+        "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+        "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
+        }
+    };
+
+    static const char message1[] = "abc";
+    static const char message2a[] = "abcdbcdecdefdefgefghfghighijhi"
+                                    "jkijkljklmklmnlmnomnopnopq";
+    static const char message2b[] = "abcdefghbcdefghicdefghijdefghijkefghij"
+                                    "klfghijklmghijklmnhijklmnoijklmnopjklm"
+                                    "nopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+    unsigned char *message3;
+    unsigned int message3_len = 1000000;
+    unsigned char digest[SHA512_DIGEST_SIZE];
+
+    message3 = malloc(message3_len);
+    if (message3 == NULL) {
+        fprintf(stderr, "Can't allocate memory\n");
+        return -1;
+    }
+    memset(message3, 'a', message3_len);
+
+    printf("SHA-2 FIPS 180-2 Validation tests\n\n");
+    printf("SHA-224 Test vectors\n");
+
+    sha224((const unsigned char *) message1, strlen(message1), digest);
+    test(vectors[0][0], digest, SHA224_DIGEST_SIZE);
+    sha224((const unsigned char *) message2a, strlen(message2a), digest);
+    test(vectors[0][1], digest, SHA224_DIGEST_SIZE);
+    sha224(message3, message3_len, digest);
+    test(vectors[0][2], digest, SHA224_DIGEST_SIZE);
+    printf("\n");
+
+    printf("SHA-256 Test vectors\n");
+
+    sha256((const unsigned char *) message1, strlen(message1), digest);
+    test(vectors[1][0], digest, SHA256_DIGEST_SIZE);
+    sha256((const unsigned char *) message2a, strlen(message2a), digest);
+    test(vectors[1][1], digest, SHA256_DIGEST_SIZE);
+    sha256(message3, message3_len, digest);
+    test(vectors[1][2], digest, SHA256_DIGEST_SIZE);
+    printf("\n");
+
+    printf("SHA-384 Test vectors\n");
+
+    sha384((const unsigned char *) message1, strlen(message1), digest);
+    test(vectors[2][0], digest, SHA384_DIGEST_SIZE);
+    sha384((const unsigned char *)message2b, strlen(message2b), digest);
+    test(vectors[2][1], digest, SHA384_DIGEST_SIZE);
+    sha384(message3, message3_len, digest);
+    test(vectors[2][2], digest, SHA384_DIGEST_SIZE);
+    printf("\n");
+
+    printf("SHA-512 Test vectors\n");
+
+    sha512((const unsigned char *) message1, strlen(message1), digest);
+    test(vectors[3][0], digest, SHA512_DIGEST_SIZE);
+    sha512((const unsigned char *) message2b, strlen(message2b), digest);
+    test(vectors[3][1], digest, SHA512_DIGEST_SIZE);
+    sha512(message3, message3_len, digest);
+    test(vectors[3][2], digest, SHA512_DIGEST_SIZE);
+    printf("\n");
+
+    printf("All tests passed.\n");
+
+    return 0;
+}
+
+#endif /* TEST_VECTORS */
+

+ 112 - 0
emmc_hal_lib/mmc-utils/3rdparty/hmac_sha/sha2.h

@@ -0,0 +1,112 @@
+/*
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 02/02/2007
+ * Issue date:  04/30/2005
+ *
+ * Since this code has been incorporated into a GPLv2 project, it is
+ * distributed under GPLv2 inside mmc-utils.  The original BSD license
+ * that the code was released under is included below for clarity.
+ *
+ * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SHA2_H
+#define SHA2_H
+
+#define SHA224_DIGEST_SIZE ( 224 / 8)
+#define SHA256_DIGEST_SIZE ( 256 / 8)
+#define SHA384_DIGEST_SIZE ( 384 / 8)
+#define SHA512_DIGEST_SIZE ( 512 / 8)
+
+#define SHA256_BLOCK_SIZE  ( 512 / 8)
+#define SHA512_BLOCK_SIZE  (1024 / 8)
+#define SHA384_BLOCK_SIZE  SHA512_BLOCK_SIZE
+#define SHA224_BLOCK_SIZE  SHA256_BLOCK_SIZE
+
+#ifndef SHA2_TYPES
+#define SHA2_TYPES
+typedef unsigned char uint8;
+typedef unsigned int  uint32;
+typedef unsigned long long uint64;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    unsigned int tot_len;
+    unsigned int len;
+    unsigned char block[2 * SHA256_BLOCK_SIZE];
+    uint32 h[8];
+} sha256_ctx;
+
+typedef struct {
+    unsigned int tot_len;
+    unsigned int len;
+    unsigned char block[2 * SHA512_BLOCK_SIZE];
+    uint64 h[8];
+} sha512_ctx;
+
+typedef sha512_ctx sha384_ctx;
+typedef sha256_ctx sha224_ctx;
+
+void sha224_init(sha224_ctx *ctx);
+void sha224_update(sha224_ctx *ctx, const unsigned char *message,
+                   unsigned int len);
+void sha224_final(sha224_ctx *ctx, unsigned char *digest);
+void sha224(const unsigned char *message, unsigned int len,
+            unsigned char *digest);
+
+void sha256_init(sha256_ctx * ctx);
+void sha256_update(sha256_ctx *ctx, const unsigned char *message,
+                   unsigned int len);
+void sha256_final(sha256_ctx *ctx, unsigned char *digest);
+void sha256(const unsigned char *message, unsigned int len,
+            unsigned char *digest);
+
+void sha384_init(sha384_ctx *ctx);
+void sha384_update(sha384_ctx *ctx, const unsigned char *message,
+                   unsigned int len);
+void sha384_final(sha384_ctx *ctx, unsigned char *digest);
+void sha384(const unsigned char *message, unsigned int len,
+            unsigned char *digest);
+
+void sha512_init(sha512_ctx *ctx);
+void sha512_update(sha512_ctx *ctx, const unsigned char *message,
+                   unsigned int len);
+void sha512_final(sha512_ctx *ctx, unsigned char *digest);
+void sha512(const unsigned char *message, unsigned int len,
+            unsigned char *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !SHA2_H */
+

+ 12 - 0
emmc_hal_lib/mmc-utils/Android.mk

@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES:= mmc.c mmc_cmds.c
+LOCAL_SRC_FILES += 3rdparty/hmac_sha/sha2.c 3rdparty/hmac_sha/hmac_sha2.c
+LOCAL_MODULE := mmc_utils
+LOCAL_SHARED_LIBRARIES := libcutils libc
+LOCAL_C_INCLUDES+= $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/mmc-utils
+include $(BUILD_EXECUTABLE)

+ 59 - 0
emmc_hal_lib/mmc-utils/Makefile

@@ -0,0 +1,59 @@
+CC := $(CROSS_COMPILE)gcc
+AM_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
+CFLAGS ?= -g -O2
+objects = \
+	mmc.o \
+	mmc_cmds.o \
+	lsmmc.o \
+	csi_rpmb.o \
+	csi_test.o \
+	3rdparty/hmac_sha/hmac_sha2.o \
+	3rdparty/hmac_sha/sha2.o
+
+CHECKFLAGS = -Wall -Werror -Wuninitialized -Wundef
+
+DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
+
+override CFLAGS := $(CHECKFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+INSTALL = install
+prefix ?= /usr/local
+bindir = $(prefix)/bin
+LIBS=
+RESTORE_LIBS=
+
+progs = mmc
+
+# make C=1 to enable sparse
+ifdef C
+	check = sparse $(CHECKFLAGS)
+endif
+
+all: $(progs) manpages
+	@echo CC=$(CC)
+.c.o:
+ifdef C
+	$(check) $<
+endif
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -c $< -o $@
+
+mmc: $(objects)
+	$(CC) $(CFLAGS) -o $@ $(objects) $(LDFLAGS) $(LIBS)
+
+manpages:
+	$(MAKE) -C man
+
+install-man:
+	$(MAKE) -C man install
+
+clean:
+	rm -f $(progs) $(objects)
+	$(MAKE) -C man clean
+
+install: $(progs) install-man
+	$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
+	$(INSTALL) $(progs) $(DESTDIR)$(bindir)
+
+-include $(foreach obj,$(objects), $(dir $(obj))/.$(notdir $(obj)).d)
+
+.PHONY: all clean install manpages install-man

+ 293 - 0
emmc_hal_lib/mmc-utils/csi_rpmb.c

@@ -0,0 +1,293 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "3rdparty/hmac_sha/hmac_sha2.h"
+#include "mmc.h"
+#include "csi_rpmb.h"
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+struct rpmb_frame {
+	u_int8_t  stuff[196];
+	u_int8_t  key_mac[32];
+	u_int8_t  data[256];
+	u_int8_t  nonce[16];
+	u_int32_t write_counter;
+	u_int16_t addr;
+	u_int16_t block_count;
+	u_int16_t result;
+	u_int16_t req_resp;
+};
+
+extern int rpmb_read_counter(int dev_fd, unsigned int *cnt);
+extern int do_rpmb_op(int fd, const struct rpmb_frame *frame_in,
+		struct rpmb_frame *frame_out, unsigned int out_cnt);
+
+/**
+  \brief       Initialize rpmb interface.
+  \param[in]   ctx    Context to operate
+  \return      Error code
+*/
+hal_error_t csi_rpmb_init(csi_hal_rpmb_ctx_t *ctx, char *device)
+{
+	int dev_fd;
+
+	assert(device != NULL);
+
+	dev_fd = open(device, O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open");
+		return CSI_HAL_ERROR;
+	}
+
+	ctx->device = device;
+	ctx->dev_fd = dev_fd;
+
+	return CSI_HAL_SUCCESS;
+}
+
+/**
+  \brief       De-initialize rpmb.
+  \param[in]   ctx    Context to operate
+  \return      None
+*/
+void csi_rpmb_uninit(csi_hal_rpmb_ctx_t *ctx)
+{
+	close(ctx->dev_fd);
+}
+
+int _do_csi_rpmb_write_key(int dev_fd, uint8_t *key)
+{
+	int ret;
+	struct rpmb_frame frame_in = {
+		.req_resp = htobe16(MMC_RPMB_WRITE_KEY)
+	}, frame_out;
+
+	/* Read the auth key */
+	memcpy(frame_in.key_mac, key, sizeof(frame_in.key_mac));
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, &frame_out, 1);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out.result != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n",
+			   be16toh(frame_out.result));
+		exit(1);
+	}
+
+	return ret;
+}
+
+int do_csi_rpmb_write_block(int dev_fd, enum hal_rpmb_op_type type, uint8_t *data, uint8_t *key_value, uint16_t addr, uint32_t blocks)
+{
+	int ret;
+	unsigned char key[32];
+	unsigned int cnt;
+	struct rpmb_frame frame_in = {
+		.req_resp    = htobe16(MMC_RPMB_WRITE),
+		.block_count = htobe16(1)
+	}, frame_out;
+
+	assert(data != NULL && key_value != NULL && dev_fd >= 0);
+	assert(type == MMC_RPMB_WRITE_KEY || type == MMC_RPMB_WRITE);
+
+	if (type == MMC_RPMB_WRITE_KEY)
+		return _do_csi_rpmb_write_key(dev_fd, key_value);
+
+	/* Get key mac */
+	memcpy(key, key_value, sizeof(key));
+
+	while (blocks) {
+		ret = rpmb_read_counter(dev_fd, &cnt);
+		/* Check RPMB response */
+		if (ret != 0) {
+			printf("RPMB read counter operation failed, retcode 0x%04x\n", ret);
+			exit(1);
+		}
+		frame_in.write_counter = htobe32(cnt);
+
+		/* Get block address */
+		frame_in.addr = htobe16(addr);
+
+		/* Read 256b data */
+		memcpy(frame_in.data, data, sizeof(frame_in.data));
+
+		/* Calculate HMAC SHA256 */
+		hmac_sha256(
+			key, sizeof(key),
+			frame_in.data, sizeof(frame_in) - offsetof(struct rpmb_frame, data),
+			frame_in.key_mac, sizeof(frame_in.key_mac));
+
+		/* Execute RPMB op */
+		ret = do_rpmb_op(dev_fd, &frame_in, &frame_out, 1);
+		if (ret != 0) {
+			perror("RPMB ioctl failed");
+			exit(1);
+		}
+
+		/* Check RPMB response */
+		if (frame_out.result != 0) {
+			printf("RPMB operation failed, retcode 0x%04x\n", be16toh(frame_out.result));
+			exit(1);
+		}
+
+		addr += 1;	/* half sector */
+		blocks -= 1;
+		data += sizeof(frame_in.data);
+
+		memset(&frame_out, 0, sizeof(frame_out));
+		memset(&frame_in, 0, sizeof(frame_in));
+		frame_in.req_resp = htobe16(MMC_RPMB_WRITE);
+		frame_in.block_count = htobe16(1);
+	}
+
+	return ret;
+}
+
+int do_csi_rpmb_read_block(int dev_fd, uint8_t *data, uint8_t *key_value, uint16_t addr, uint32_t blocks)
+{
+	int i, ret;
+	unsigned char mac[32];
+	hmac_sha256_ctx ctx;
+	struct rpmb_frame *frame_out = NULL;
+	/*
+	 * for reading RPMB, number of blocks is set by CMD23 only, the packet
+	 * frame field for that is set to 0. So, the type is not u16 but uint!
+	 */
+	unsigned int blocks_cnt;
+	unsigned char key[32];
+	struct rpmb_frame frame_in = {
+		.req_resp    = htobe16(MMC_RPMB_READ),
+	}, *frame_out_p;
+
+	/* Get key mac */
+	memcpy(key, key_value, sizeof(key));
+
+	/* Get block address */
+	frame_in.addr = htobe16(addr);
+
+	/* Get blocks count */
+	blocks_cnt = blocks;
+	if (!blocks_cnt) {
+		printf("please, specify valid blocks count number\n");
+		exit(1);
+	}
+
+	frame_out_p = calloc(sizeof(*frame_out_p), blocks_cnt);
+	if (!frame_out_p) {
+		printf("can't allocate memory for RPMB outer frames\n");
+		exit(1);
+	}
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, frame_out_p, blocks_cnt);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out_p[blocks_cnt - 1].result != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n",
+			   be16toh(frame_out_p[blocks_cnt - 1].result));
+		exit(1);
+	}
+
+	/* Do we have to verify data against key? */
+	hmac_sha256_init(&ctx, key, sizeof(key));
+	for (i = 0; i < blocks_cnt; i++) {
+		frame_out = &frame_out_p[i];
+		hmac_sha256_update(&ctx, frame_out->data, sizeof(*frame_out) - offsetof(struct rpmb_frame, data));
+	}
+
+	hmac_sha256_final(&ctx, mac, sizeof(mac));
+
+	/* Impossible */
+	assert(frame_out);
+
+	/* Compare calculated MAC and MAC from last frame */
+	if (memcmp(mac, frame_out->key_mac, sizeof(mac))) {
+		printf("RPMB MAC missmatch\n");
+		exit(1);
+	}
+
+	/* Write data */
+	for (i = 0; i < blocks_cnt; i++) {
+		struct rpmb_frame *frame_out = &frame_out_p[i];
+
+		memcpy(data, frame_out->data, sizeof(frame_out->data));
+		data += sizeof(frame_out->data);
+	}
+
+	free(frame_out_p);
+
+	return ret;
+}
+
+/**
+  \brief       RPMB write data, authenticated data and write to RPMB.
+  \param[in]   ctx        Context to operate
+  \param[in]   addr [in]        address, address in block.
+  \param[in]   blocks [in]      write block number. block size 256 bytes.
+  \param[in]   data [in]
+  \return      Error code
+*/
+hal_error_t csi_rpmb_write_block(csi_hal_rpmb_ctx_t *ctx, uint16_t addr,
+                                 uint32_t blocks, uint8_t *data)
+{
+	int ret, dev_fd;
+	uint8_t *key_value;
+	enum hal_rpmb_op_type type;
+
+	assert(ctx != NULL && data != NULL);
+
+	dev_fd = ctx->dev_fd;
+	key_value = ctx->key_mac;
+	type = ctx->rpmb_op_type;
+
+	ret = do_csi_rpmb_write_block(dev_fd, type, data, key_value, addr, blocks);
+	if (ret)
+		return CSI_HAL_ERROR;
+	else
+		return CSI_HAL_SUCCESS;
+}
+
+/**
+  \brief       RPMB read data, check .authentication tag and return data.
+  \param[in]   ctx        Context to operate
+  \param[in]   addr [in]        address
+  \param[in]   blocks [in]      write block number.
+  \return      Error code
+*/
+hal_error_t csi_rpmb_read_block(csi_hal_rpmb_ctx_t *ctx, uint16_t addr,
+                                uint32_t blocks, uint8_t *data)
+{
+	int ret, dev_fd;
+	uint8_t *key_value;
+
+	assert(ctx != NULL && data != NULL);
+
+	dev_fd = ctx->dev_fd;
+	key_value = ctx->key_mac;
+
+	ret = do_csi_rpmb_read_block(dev_fd, data, key_value, addr, blocks);
+	if (ret)
+		return CSI_HAL_ERROR;
+	else
+		return CSI_HAL_SUCCESS;
+}

+ 62 - 0
emmc_hal_lib/mmc-utils/csi_rpmb.h

@@ -0,0 +1,62 @@
+#ifndef _CSI_RPMB_H
+#define _CSI_RPMB_H
+
+#include <stdint.h>
+
+#define CSI_HAL_ERROR		-1
+#define CSI_HAL_SUCCESS		0
+
+enum hal_rpmb_op_type {
+	MMC_RPMB_WRITE_KEY = 0x01,
+	MMC_RPMB_READ_CNT  = 0x02,
+	MMC_RPMB_WRITE     = 0x03,
+	MMC_RPMB_READ      = 0x04,
+};
+
+typedef int	hal_error_t;
+
+typedef struct _csi_hal_rpmb_ctx {
+	char *device;
+	int dev_fd;
+	enum hal_rpmb_op_type rpmb_op_type;
+	uint8_t key_mac[32];
+}csi_hal_rpmb_ctx_t;
+
+
+/**
+  \brief       Initialize rpmb interface.
+  \param[in]   ctx    Context to operate
+  \return      Error code
+*/
+hal_error_t csi_rpmb_init(csi_hal_rpmb_ctx_t *ctx,  char *device);
+
+/**
+  \brief       De-initialize rpmb.
+  \param[in]   ctx    Context to operate
+  \return      None
+*/
+void csi_rpmb_uninit(csi_hal_rpmb_ctx_t *ctx);
+
+/**
+  \brief       RPMB read data, check .authentication tag and return data.
+  \param[in]   ctx        Context to operate
+  \param[in]   addr [in]        address
+  \param[in]   blocks [in]      write block number.
+  \return      Error code
+*/
+hal_error_t csi_rpmb_read_block(csi_hal_rpmb_ctx_t *ctx, uint16_t addr,
+                                uint32_t blocks, uint8_t *data);
+
+/**
+  \brief       RPMB write data, authenticated data and write to RPMB.
+  \param[in]   ctx        Context to operate
+  \param[in]   addr [in]        address, address in block.
+  \param[in]   blocks [in]      write block number. block size 256 bytes.
+  \param[in]   data [in]
+  \return      Error code
+*/
+hal_error_t csi_rpmb_write_block(csi_hal_rpmb_ctx_t *ctx, uint16_t addr,
+                                 uint32_t blocks, uint8_t *data);
+
+
+#endif

+ 108 - 0
emmc_hal_lib/mmc-utils/csi_test.c

@@ -0,0 +1,108 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include "csi_rpmb.h"
+
+#define HALF_SECTOR_BYTES	256
+#define BLOCK_NUM		2
+#define BLOCK_START		2
+
+uint8_t key[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0xa, 0xa, 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, 0xf};
+
+#define DO_IO(func, fd, buf, nbyte)					\
+	({												\
+		ssize_t ret = 0, r;							\
+		do {										\
+			r = func(fd, buf + ret, nbyte - ret);	\
+			if (r < 0 && errno != EINTR) {			\
+				ret = -1;							\
+				break;								\
+			}										\
+			else if (r > 0)							\
+				ret += r;							\
+		} while (r != 0 && (size_t)ret != nbyte);	\
+													\
+		ret;										\
+	})
+
+int main()
+{
+	int i, key_fd;
+	hal_error_t ret;
+	csi_hal_rpmb_ctx_t rpmb_ctx = { 0 };
+	unsigned char write_data[HALF_SECTOR_BYTES * BLOCK_NUM], read_data[HALF_SECTOR_BYTES * BLOCK_NUM] = { 0 };
+	char *devicefile = "/dev/mmcblk0rpmb";
+
+	for (i = 0; i < (HALF_SECTOR_BYTES * BLOCK_NUM); i++) {
+		if (i < 256)
+			write_data[i] = i % 256;
+		else
+			write_data[i] = 256 - (i % 256);
+	}
+
+	//memcpy(rpmb_ctx.key_mac, key, sizeof(key));
+	key_fd = open("/home/root/rpmbkey", O_RDONLY);
+	if (key_fd < 0) {
+		perror("can't open key file");
+		exit(1);
+	}
+
+	ret = DO_IO(read, key_fd, rpmb_ctx.key_mac, sizeof(rpmb_ctx.key_mac));
+	if (ret < 0) {
+		perror("read the key");
+		exit(1);
+	} else if (ret != sizeof(key)) {
+		printf("Auth key must be %lu bytes length, but we read only %d, exit\n",
+			   (unsigned long)sizeof(rpmb_ctx.key_mac),
+			   ret);
+		exit(1);
+	}
+
+	printf("Key ascii:\n");
+	for (i = 0; i < sizeof(rpmb_ctx.key_mac); i++)
+		printf("%d", rpmb_ctx.key_mac[i]);
+
+	printf("\n");
+
+	printf("Key character:\n");
+	for (i = 0; i < sizeof(rpmb_ctx.key_mac); i++)
+		printf("%c", rpmb_ctx.key_mac[i]);
+
+	printf("\n");
+
+	rpmb_ctx.rpmb_op_type = MMC_RPMB_WRITE;
+	ret = csi_rpmb_init(&rpmb_ctx, devicefile);
+	if (ret) {
+		printf("failed to init csi rpmb device\n");
+		exit(1);
+	}
+
+	ret = csi_rpmb_write_block(&rpmb_ctx, BLOCK_START, BLOCK_NUM, write_data);
+	if (ret) {
+		printf("failed to write rpmb device\n");
+		exit(1);
+	}
+
+	ret = csi_rpmb_read_block(&rpmb_ctx, BLOCK_START, BLOCK_NUM, read_data);
+	if (ret) {
+		printf("failed to read rpmb device\n");
+		exit(1);
+	}
+
+	for (i = 0; i < sizeof(read_data); i++) {
+		if (i % 16 == 0)
+			printf("\n");
+		if (i == 256)
+			printf("\n");
+
+		printf("%d\t", read_data[i]);
+	}
+	printf("\n");
+
+	csi_rpmb_uninit(&rpmb_ctx);
+
+	return 0;
+}

+ 2431 - 0
emmc_hal_lib/mmc-utils/lsmmc.c

@@ -0,0 +1,2431 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010-2011
+ * Author: Sebastian Rasmussen <sebastian.rasmussen@stericsson.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials
+ *      provided with the distribution.
+ *   3. Neither the name of the ST-Ericsson SA nor the names of its
+ *      contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written
+ *      permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "mmc.h"
+
+#define MASKTOBIT0(high)	\
+	((high >= 0) ? ((1ull << ((high) + 1ull)) - 1ull) : 0ull)
+#define MASK(high, low)		(MASKTOBIT0(high) & ~MASKTOBIT0(low - 1))
+#define BITS(value, high, low)	(((value) & MASK((high), (low))) >> (low))
+#define IDS_MAX			256
+
+struct config {
+	char *idsfile;
+	char *dir;
+	bool verbose;
+	int interfaces;
+	char **interface;
+	char **mmc_ids;
+	char **sd_ids;
+
+	char *type;
+	char *cid;
+	char *csd;
+	char *scr;
+	char *ext_csd;
+};
+
+enum REG_TYPE {
+	CID = 0,
+	CSD,
+	SCR,
+	EXT_CSD,
+};
+
+struct ids_database {
+	char *type;
+	int id;
+	char *manufacturer;
+};
+
+struct ids_database database[] = {
+	{
+		.type = "sd",
+		.id = 0x01,
+		.manufacturer = "Panasonic",
+	},
+	{
+		.type = "sd",
+		.id = 0x02,
+		.manufacturer = "Toshiba/Kingston/Viking",
+	},
+	{
+		.type = "sd",
+		.id = 0x03,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "sd",
+		.id = 0x08,
+		.manufacturer = "Silicon Power",
+	},
+	{
+		.type = "sd",
+		.id = 0x18,
+		.manufacturer = "Infineon",
+	},
+	{
+		.type = "sd",
+		.id = 0x1b,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x1c,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x1d,
+		.manufacturer = "Corsair",
+	},
+	{
+		.type = "sd",
+		.id = 0x1e,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x1f,
+		.manufacturer = "Kingston",
+	},
+	{
+		.type = "sd",
+		.id = 0x28,
+		.manufacturer = "Lexar",
+	},
+	{
+		.type = "sd",
+		.id = 0x30,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "sd",
+		.id = 0x33,
+		.manufacturer = "STMicroelectronics",
+	},
+	{
+		.type = "sd",
+		.id = 0x41,
+		.manufacturer = "Kingston",
+	},
+	{
+		.type = "sd",
+		.id = 0x6f,
+		.manufacturer = "STMicroelectronics",
+	},
+	{
+		.type = "sd",
+		.id = 0x89,
+		.manufacturer = "Unknown",
+	},
+	{
+		.type = "mmc",
+		.id = 0x00,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "mmc",
+		.id = 0x02,
+		.manufacturer = "Kingston/SanDisk",
+	},
+	{
+		.type = "mmc",
+		.id = 0x03,
+		.manufacturer = "Toshiba",
+	},
+	{
+		.type = "mmc",
+		.id = 0x05,
+		.manufacturer = "Unknown",
+	},
+	{
+		.type = "mmc",
+		.id = 0x06,
+		.manufacturer = "Unknown",
+	},
+	{
+		.type = "mmc",
+		.id = 0x11,
+		.manufacturer = "Toshiba",
+	},
+	{
+		.type = "mmc",
+		.id = 0x13,
+		.manufacturer = "Micron",
+	},
+	{
+		.type = "mmc",
+		.id = 0x15,
+		.manufacturer = "Samsung/SanDisk/LG",
+	},
+	{
+		.type = "mmc",
+		.id = 0x37,
+		.manufacturer = "KingMax",
+	},
+	{
+		.type = "mmc",
+		.id = 0x44,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "mmc",
+		.id = 0x2c,
+		.manufacturer = "Kingston",
+	},
+	{
+		.type = "mmc",
+		.id = 0x70,
+		.manufacturer = "Kingston",
+	},
+};
+
+/* Command line parsing functions */
+void usage(void)
+{
+	printf("Usage: print mmc [-h] [-v] <device path ...>\n");
+	printf("\n");
+	printf("Options:\n");
+	printf("\t-h\tShow this help.\n");
+	printf("\t-v\tEnable verbose mode.\n");
+}
+
+int parse_opts(int argc, char **argv, struct config *config)
+{
+	int c;
+
+	while ((c = getopt(argc, argv, "hv")) != -1) {
+		switch (c) {
+		case 'h':
+			usage();
+			return -1;
+		case 'v':
+			config->verbose = true;
+			break;
+		case '?':
+			fprintf(stderr,
+				"Unknown option '%c' encountered.\n\n", c);
+			usage();
+			return -1;
+		case ':':
+			fprintf(stderr,
+				"Argument for option '%c' missing.\n\n", c);
+			usage();
+			return -1;
+		default:
+			fprintf(stderr,
+				"Unimplemented option '%c' encountered.\n", c);
+			break;
+		}
+	}
+
+	if (optind >= argc) {
+		fprintf(stderr, "Expected mmc directory arguments.\n\n");
+		usage();
+		return -1;
+	}
+
+	config->dir = strdup(argv[optind]);
+	return 0;
+}
+
+int parse_ids(struct config *config)
+{
+	unsigned int ids_cnt = sizeof(database) / sizeof(struct ids_database);
+	unsigned int value;
+	char **ids;
+	char *type;
+	int i;
+
+	for (i = 0; i < ids_cnt; i++) {
+		type = database[i].type;
+
+		if (!strcmp(type, "mmc")) {
+			ids = config->mmc_ids;
+		} else if (!strcmp(type, "sd")) {
+			ids = config->sd_ids;
+		} else {
+			fprintf(stderr,
+				"MMC/SD id parse error, unknown type: '%s'.\n",
+				type);
+			return -1;
+		}
+
+		value = database[i].id;
+
+		if (value >= IDS_MAX) {
+			fprintf(stderr,
+				"MMC/SD id parse error, id out of range.\n");
+			return -1;
+		}
+
+		if (ids[value]) {
+			fprintf(stderr,
+				"Duplicate entries: type='%s', id='0x%1x'.\n",
+				type, value);
+			return -1;
+		}
+
+		ids[value] = database[i].manufacturer;
+	}
+
+	return 0;
+}
+
+/* MMC/SD file parsing functions */
+char *read_file(char *name)
+{
+	char line[4096];
+	char *preparsed, *start = line;
+	int len;
+	FILE *f;
+
+	f = fopen(name, "r");
+	if (!f) {
+		fprintf(stderr, "Could not open MMC/SD file '%s'.\n", name);
+		return NULL;
+	}
+
+	preparsed = fgets(line, sizeof(line), f);
+	if (!preparsed) {
+		if (ferror(f))
+			fprintf(stderr, "Could not read MMC/SD file '%s'.\n",
+				name);
+		else
+			fprintf(stderr,
+				"Could not read data from MMC/SD file '%s'.\n",
+				name);
+
+		if (fclose(f))
+			fprintf(stderr, "Could not close MMC/SD file '%s'.\n",
+				name);
+		return NULL;
+	}
+
+	if (fclose(f)) {
+		fprintf(stderr, "Could not close MMC/SD file '%s'.\n", name);
+		return NULL;
+	}
+
+	line[sizeof(line) - 1] = '\0';
+	len = strlen(line);
+
+	while (len > 0 && isspace(line[len - 1]))
+		len--;
+
+	while (len > 0 && isspace(*start)) {
+		start++;
+		len--;
+	}
+	memmove(line, start, len);
+	line[len] = '\0';
+
+	return strdup(line);
+}
+
+/* Hexadecimal string parsing functions */
+char *to_binstr(char *hexstr)
+{
+	char *bindigits[] = {
+		"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+		"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111",
+	};
+	char *binstr, *tail;
+
+	binstr = calloc(strlen(hexstr) * 4 + 1, sizeof(char));
+	if (!binstr)
+		return NULL;
+
+	tail = binstr;
+
+	while (hexstr && *hexstr != '\0') {
+		if (!isxdigit(*hexstr)) {
+			free(binstr);
+			return NULL;
+		}
+
+		if (isdigit(*hexstr))
+			strcat(tail, bindigits[*hexstr - '0']);
+		else if (islower(*hexstr))
+			strcat(tail, bindigits[*hexstr - 'a' + 10]);
+		else
+			strcat(tail, bindigits[*hexstr - 'A' + 10]);
+
+		hexstr++;
+		tail += 4;
+	}
+
+	return binstr;
+}
+
+void bin_to_unsigned(unsigned int *u, char *binstr, int width)
+{
+	*u = 0;
+	assert(width <= 32);
+
+	while (binstr && *binstr != '\0' && width > 0) {
+		*u <<= 1;
+		*u |= *binstr == '0' ? 0 : 1;
+
+		binstr++;
+		width--;
+	}
+}
+
+void bin_to_ascii(char *a, char *binstr, int width)
+{
+	assert(width % 8 == 0);
+	*a = '\0';
+
+	while (binstr && *binstr != '\0' && width > 0) {
+		unsigned int u;
+		char c[2] = { '\0', '\0' };
+		char *s = &c[0];
+
+		bin_to_unsigned(&u, binstr, 8);
+		c[0] = u;
+
+		strcat(a, s);
+		binstr += 8;
+		width -= 8;
+	}
+}
+
+void parse_bin(char *hexstr, char *fmt, ...)
+{
+	va_list args;
+	char *origstr;
+	char *binstr;
+	unsigned long width = 0;
+
+	binstr = to_binstr(hexstr);
+	origstr = binstr;
+
+	va_start(args, fmt);
+
+	while (binstr && fmt && *fmt != '\0') {
+		if (isdigit(*fmt)) {
+			char *rest;
+
+			errno = 0;
+			width = strtoul(fmt, &rest, 10);
+			if (width == ULONG_MAX && errno != 0)
+				fprintf(stderr, "strtoul()");
+			fmt = rest;
+		} else if (*fmt == 'u') {
+			unsigned int *u = va_arg(args, unsigned int *);
+
+			if (u)
+				bin_to_unsigned(u, binstr, width);
+			binstr += width;
+			width = 0;
+			fmt++;
+		} else if (*fmt == 'r') {
+			binstr += width;
+			width = 0;
+			fmt++;
+		} else if (*fmt == 'a') {
+			char *c = va_arg(args, char *);
+
+			if (c)
+				bin_to_ascii(c, binstr, width);
+			binstr += width;
+			width = 0;
+			fmt++;
+		} else {
+			fmt++;
+		}
+	}
+
+	va_end(args);
+	free(origstr);
+}
+
+/* MMC/SD information parsing functions */
+void print_sd_cid(struct config *config, char *cid)
+{
+	static const char *months[] = {
+		"jan", "feb", "mar", "apr", "may", "jun",
+		"jul", "aug", "sep", "oct", "nov", "dec",
+		"invalid0", "invalid1", "invalid2", "invalid3",
+	};
+	unsigned int mid;
+	char oid[3];
+	char pnm[6];
+	unsigned int prv_major;
+	unsigned int prv_minor;
+	unsigned int psn;
+	unsigned int mdt_month;
+	unsigned int mdt_year;
+	unsigned int crc;
+
+	parse_bin(cid, "8u16a40a4u4u32u4r8u4u7u1r",
+		&mid, &oid[0], &pnm[0], &prv_major, &prv_minor, &psn,
+		&mdt_year, &mdt_month, &crc);
+
+	oid[2] = '\0';
+	pnm[5] = '\0';
+
+	if (config->verbose) {
+		printf("======SD/CID======\n");
+
+		printf("\tMID: 0x%02x (", mid);
+		if (config->sd_ids[mid])
+			printf("%s)\n", config->sd_ids[mid]);
+		else
+			printf("Unlisted)\n");
+
+		printf("\tOID: %s\n", oid);
+		printf("\tPNM: %s\n", pnm);
+		printf("\tPRV: 0x%01x%01x ", prv_major, prv_minor);
+		printf("(%d.%d)\n", prv_major, prv_minor);
+		printf("\tPSN: 0x%08x\n", psn);
+		printf("\tMDT: 0x%02x%01x %d %s\n", mdt_year, mdt_month,
+		       2000 + mdt_year, months[mdt_month]);
+		printf("\tCRC: 0x%02x\n", crc);
+	} else {
+		if (config->sd_ids[mid])
+			printf("manufacturer: '%s' '%s'\n",
+			       config->sd_ids[mid], oid);
+		else
+			printf("manufacturer: 'Unlisted' '%s'\n", oid);
+
+		printf("product: '%s' %d.%d\n", pnm, prv_major, prv_minor);
+		printf("serial: 0x%08x\n", psn);
+		printf("manfacturing date: %d %s\n", 2000 + mdt_year,
+		       months[mdt_month]);
+	}
+}
+
+void print_mmc_cid(struct config *config, char *cid)
+{
+	static const char *months[] = {
+		"jan", "feb", "mar", "apr", "may", "jun",
+		"jul", "aug", "sep", "oct", "nov", "dec",
+		"invalid0", "invalid1", "invalid2", "invalid3",
+	};
+	unsigned int mid;
+	unsigned int cbx;
+	unsigned int oid;
+	char pnm[7];
+	unsigned int prv_major;
+	unsigned int prv_minor;
+	unsigned int psn;
+	unsigned int mdt_month;
+	unsigned int mdt_year;
+	unsigned int crc;
+
+	parse_bin(cid, "8u6r2u8u48a4u4u32u4u4u7u1r",
+		&mid, &cbx, &oid, &pnm[0], &psn, &prv_major, &prv_minor,
+		&mdt_year, &mdt_month, &crc);
+
+	pnm[6] = '\0';
+
+	if (config->verbose) {
+		printf("======MMC/CID======\n");
+
+		printf("\tMID: 0x%02x (", mid);
+		if (config->mmc_ids[mid])
+			printf("%s)\n", config->mmc_ids[mid]);
+		else
+			printf("Unlisted)\n");
+
+		printf("\tCBX: 0x%01x (", cbx);
+		switch (cbx) {
+		case 0:
+			printf("card)\n");
+			break;
+		case 1:
+			printf("BGA)\n");
+			break;
+		case 2:
+			printf("PoP)\n");
+			break;
+		case 3:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tOID: 0x%01x\n", oid);
+		printf("\tPNM: %s\n", pnm);
+		printf("\tPRV: 0x%01x%01x ", prv_major, prv_minor);
+		printf("(%d.%d)\n", prv_major, prv_minor);
+		printf("\tPSN: 0x%08x\n", psn);
+		printf("\tMDT: 0x%01x%01x %d %s\n", mdt_month, mdt_year,
+		       1997 + mdt_year, months[mdt_month]);
+		printf("\tCRC: 0x%02x\n", crc);
+	} else {
+		if (config->mmc_ids[mid])
+			printf("manufacturer: '%s' '%c'\n",
+			       config->mmc_ids[mid], oid);
+		else
+			printf("manufacturer: 'Unlisted' '%c'\n", oid);
+
+		printf("product: '%s' %d.%d\n", pnm, prv_major, prv_minor);
+		printf("serial: 0x%08x\n", psn);
+		printf("manfacturing date: %d %s\n", 1997 + mdt_year,
+		       months[mdt_month]);
+	}
+}
+
+void print_sd_csd(struct config *config, char *csd)
+{
+	unsigned int csd_structure;
+	unsigned int taac_timevalue;
+	unsigned int taac_timeunit;
+	unsigned int nsac;
+	unsigned int tran_speed_timevalue;
+	unsigned int tran_speed_transferrateunit;
+	unsigned int ccc;
+	unsigned int read_bl_len;
+	unsigned int read_bl_partial;
+	unsigned int write_blk_misalign;
+	unsigned int read_blk_misalign;
+	unsigned int dsr_imp;
+	unsigned int c_size;
+	unsigned int vdd_r_curr_min;
+	unsigned int vdd_r_curr_max;
+	unsigned int vdd_w_curr_min;
+	unsigned int vdd_w_curr_max;
+	unsigned int c_size_mult;
+	unsigned int erase_blk_en;
+	unsigned int sector_size;
+	unsigned int wp_grp_size;
+	unsigned int wp_grp_enable;
+	unsigned int r2w_factor;
+	unsigned int write_bl_len;
+	unsigned int write_bl_partial;
+	unsigned int file_format_grp;
+	unsigned int copy;
+	unsigned int perm_write_protect;
+	unsigned int tmp_write_protect;
+	unsigned int file_format;
+	unsigned int crc;
+	unsigned int taac;
+	unsigned int tran_speed;
+
+	parse_bin(csd, "2u", &csd_structure);
+
+	if (csd_structure == 0) {
+		parse_bin(csd, "2u6r1r4u3u8u1r4u3u12u4u1u1u1u1u2r12u3u3u3u3u3u"
+			  "1u7u7u1u2r3u4u1u5r1u1u1u1u2u2r7u1r",
+			  NULL, &taac_timevalue, &taac_timeunit, &nsac,
+			  &tran_speed_timevalue,
+			  &tran_speed_transferrateunit, &ccc,
+			  &read_bl_len, &read_bl_partial,
+			  &write_blk_misalign, &read_blk_misalign,
+			  &dsr_imp, &c_size, &vdd_r_curr_min,
+			  &vdd_r_curr_max, &vdd_w_curr_min,
+			  &vdd_w_curr_max, &c_size_mult, &erase_blk_en,
+			  &sector_size, &wp_grp_size, &wp_grp_enable,
+			  &r2w_factor, &write_bl_len, &write_bl_partial,
+			  &file_format_grp, &copy, &perm_write_protect,
+			  &tmp_write_protect, &file_format, &crc);
+	} else if (csd_structure == 1) {
+		parse_bin(csd, "2u6r1r4u3u8u1r4u3u12u4u1u1u1u1u6r22u1r1u7u7u1u"
+			  "2r3u4u1u5r1u1u1u1u2u2r7u1r",
+			  NULL, &taac_timevalue, &taac_timeunit, &nsac,
+			  &tran_speed_timevalue,
+			  &tran_speed_transferrateunit, &ccc,
+			  &read_bl_len, &read_bl_partial,
+			  &write_blk_misalign, &read_blk_misalign,
+			  &dsr_imp, &c_size, &erase_blk_en, &sector_size,
+			  &wp_grp_size, &wp_grp_enable, &r2w_factor,
+			  &write_bl_len, &write_bl_partial,
+			  &file_format_grp, &copy, &perm_write_protect,
+			  &tmp_write_protect, &file_format, &crc);
+
+		vdd_r_curr_min = 0;
+		c_size_mult = 0;
+	} else {
+		printf("Unknown CSD structure: 0x%1x\n", csd_structure);
+		return;
+	}
+
+	taac = taac_timevalue << 3 | taac_timeunit;
+	tran_speed = tran_speed_timevalue << 3 | tran_speed_transferrateunit;
+
+	if (config->verbose) {
+		float value;
+		unsigned long long blocks = 0;
+		int block_size = 0;
+		unsigned long long memory_capacity;
+
+		printf("======SD/CSD======\n");
+
+		printf("\tCSD_STRUCTURE: %d\n", csd_structure);
+		printf("\tTAAC: 0x%02x (", taac);
+
+		switch (taac_timevalue) {
+		case 0x0:
+			value = 0.0f;
+			break;
+		case 0x1:
+			value = 1.0f;
+			break;
+		case 0x2:
+			value = 1.2f;
+			break;
+		case 0x3:
+			value = 1.3f;
+			break;
+		case 0x4:
+			value = 1.5f;
+			break;
+		case 0x5:
+			value = 2.0f;
+			break;
+		case 0x6:
+			value = 2.5f;
+			break;
+		case 0x7:
+			value = 3.0f;
+			break;
+		case 0x8:
+			value = 3.5f;
+			break;
+		case 0x9:
+			value = 4.0f;
+			break;
+		case 0xa:
+			value = 4.5f;
+			break;
+		case 0xb:
+			value = 5.0f;
+			break;
+		case 0xc:
+			value = 5.5f;
+			break;
+		case 0xd:
+			value = 6.0f;
+			break;
+		case 0xe:
+			value = 7.0f;
+			break;
+		case 0xf:
+			value = 8.0f;
+			break;
+		default:
+			value = 0.0f;
+			break;
+		}
+
+		switch (taac_timeunit) {
+		case 0x0:
+			printf("%.2fns)\n", value * 1.0f);
+			break;
+		case 0x1:
+			printf("%.2fns)\n", value * 10.0f);
+			break;
+		case 0x2:
+			printf("%.2fns)\n", value * 100.0f);
+			break;
+		case 0x3:
+			printf("%.2fus)\n", value * 1.0f);
+			break;
+		case 0x4:
+			printf("%.2fus)\n", value * 10.0f);
+			break;
+		case 0x5:
+			printf("%.2fus)\n", value * 100.0f);
+			break;
+		case 0x6:
+			printf("%.2fms)\n", value * 1.0f);
+			break;
+		case 0x7:
+			printf("%.2fms)\n", value * 10.0f);
+			break;
+		}
+
+		if (csd_structure == 1 && taac != 0x0e)
+			printf("Warn: Invalid TAAC (should be 0x0e)\n");
+
+		printf("\tNSAC: %d clocks\n", nsac);
+		if (csd_structure == 1 && nsac != 0x00)
+			printf("Warn: Invalid NSAC (should be 0x00)\n");
+
+		printf("\tTRAN_SPEED: 0x%02x (", tran_speed);
+		switch (tran_speed_timevalue) {
+		case 0x0:
+			value = 0.0f;
+			break;
+		case 0x1:
+			value = 1.0f;
+			break;
+		case 0x2:
+			value = 1.2f;
+			break;
+		case 0x3:
+			value = 1.3f;
+			break;
+		case 0x4:
+			value = 1.5f;
+			break;
+		case 0x5:
+			value = 2.0f;
+			break;
+		case 0x6:
+			value = 2.5f;
+			break;
+		case 0x7:
+			value = 3.0f;
+			break;
+		case 0x8:
+			value = 3.5f;
+			break;
+		case 0x9:
+			value = 4.0f;
+			break;
+		case 0xa:
+			value = 4.5f;
+			break;
+		case 0xb:
+			value = 5.0f;
+			break;
+		case 0xc:
+			value = 5.5f;
+			break;
+		case 0xd:
+			value = 6.0f;
+			break;
+		case 0xe:
+			value = 7.0f;
+			break;
+		case 0xf:
+			value = 8.0f;
+			break;
+		default:
+			value = 0.0f;
+			break;
+		}
+
+		switch (tran_speed_transferrateunit) {
+		case 0x0:
+			printf("%.2fkbit/s)\n", value * 100.0f);
+			break;
+		case 0x1:
+			printf("%.2fMbit/s)\n", value * 1.0f);
+			break;
+		case 0x2:
+			printf("%.2fMbit/s)\n", value * 10.0f);
+			break;
+		case 0x3:
+			printf("%.2fMbit/s)\n", value * 100.0f);
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+		if (csd_structure == 0 &&
+		    (tran_speed != 0x32 && tran_speed != 0x5a))
+			printf("Warn: Invalid TRAN_SPEED "
+			       "(should be 0x32 or 0x5a)\n");
+		if (csd_structure == 1 && tran_speed != 0x32 &&
+		    tran_speed != 0x5a && tran_speed != 0x0b &&
+		    tran_speed != 0x2b)
+			printf("Warn: Invalid TRAN_SPEED "
+			       "(should be 0x32, 0x5a, 0x0b or 0x2b\n");
+
+		printf("\tCCC: 0x%03x (class: ", ccc);
+		if (ccc & 0x800)
+			printf("11, ");
+		if (ccc & 0x400)
+			printf("10, ");
+		if (ccc & 0x200)
+			printf("9, ");
+		if (ccc & 0x100)
+			printf("8, ");
+		if (ccc & 0x080)
+			printf("7, ");
+		if (ccc & 0x040)
+			printf("6, ");
+		if (ccc & 0x020)
+			printf("5, ");
+		if (ccc & 0x010)
+			printf("4, ");
+		if (ccc & 0x008)
+			printf("3, ");
+		if (ccc & 0x004)
+			printf("2, ");
+		if (ccc & 0x002)
+			printf("1, ");
+		if (ccc & 0x001)
+			printf("0, ");
+		printf("  )\n");
+
+		if (csd_structure == 0 &&
+		    (ccc != 0x5b5 && ccc != 0x7b5 && ccc != 0x5f5))
+			printf("Warn: Invalid CCC (should be 0x5b5, "
+			       "0x7b5 or 0x5f5)\n");
+		else if (csd_structure == 1 && ccc != 0x5b5 && ccc != 0x7b5)
+			printf("Warn: Invalid CCC (should be 0x5b5 or 0x7b5)\n");
+
+		printf("\tREAD_BL_LEN: 0x%01x (", read_bl_len);
+		switch (read_bl_len) {
+		case 0x9:
+			printf("512 bytes)\n");
+			break;
+		case 0xa:
+			printf("1024 bytes)\n");
+			break;
+		case 0xb:
+			printf("2048 bytes)\n");
+			break;
+		default:
+			printf("reserved bytes)\n");
+			break;
+		}
+
+		if (csd_structure == 1 && read_bl_len != 0x9)
+			printf("Warn: Invalid READ_BL_LEN (should be 0x9)\n");
+
+		printf("\tREAD_BL_PARTIAL: 0x%01x\n", read_bl_partial);
+		if (csd_structure == 0 && read_bl_partial != 0x01)
+			printf("Warn: Invalid READ_BL_PARTIAL (should be 0x01)\n");
+		else if (csd_structure == 1 && read_bl_partial != 0x00)
+			printf("Warn: Invalid READ_BL_PARTIAL (should be 0x00)\n");
+
+		printf("\tWRITE_BLK_MISALIGN: 0x%01x\n", write_blk_misalign);
+		if (csd_structure == 1 && write_blk_misalign != 0x00)
+			printf("Warn: Invalid WRITE_BLK_MISALIGN (should be 0x00)\n");
+
+		printf("\tREAD_BLK_MISALIGN: 0x%01x\n", read_blk_misalign);
+		if (csd_structure == 1 && read_blk_misalign != 0x00)
+			printf("Warn: Invalid READ_BLK_MISALIGN (should be 0x00)\n");
+
+		printf("\tDSR_IMP: 0x%01x\n", dsr_imp);
+
+		if (csd_structure == 0) {
+			int mult;
+			int blocknr;
+			int block_len;
+
+			printf("\tC_SIZE: 0x%03x\n", c_size);
+			printf("\tVDD_R_CURR_MIN: 0x%01x (", vdd_r_curr_min);
+			switch (vdd_r_curr_min) {
+			case 0x0:
+				printf("0.5mA)\n");
+				break;
+			case 0x1:
+				printf("1mA)\n");
+				break;
+			case 0x2:
+				printf("5mA)\n");
+				break;
+			case 0x3:
+				printf("10mA)\n");
+				break;
+			case 0x4:
+				printf("25mA)\n");
+				break;
+			case 0x5:
+				printf("35mA)\n");
+				break;
+			case 0x6:
+				printf("60mA)\n");
+				break;
+			case 0x7:
+				printf("100mA)\n");
+				break;
+			}
+
+			printf("\tVDD_R_CURR_MAX: 0x%01x (", vdd_r_curr_max);
+			switch (vdd_r_curr_max) {
+			case 0x0:
+				printf("1mA)\n");
+				break;
+			case 0x1:
+				printf("5mA)\n");
+				break;
+			case 0x2:
+				printf("10mA)\n");
+				break;
+			case 0x3:
+				printf("25mA)\n");
+				break;
+			case 0x4:
+				printf("35mA)\n");
+				break;
+			case 0x5:
+				printf("45mA)\n");
+				break;
+			case 0x6:
+				printf("80mA)\n");
+				break;
+			case 0x7:
+				printf("200mA)\n");
+				break;
+			}
+
+			printf("\tVDD_W_CURR_MIN: 0x%01x (", vdd_w_curr_min);
+			switch (vdd_w_curr_min) {
+			case 0x0:
+				printf("0.5mA)\n");
+				break;
+			case 0x1:
+				printf("1mA)\n");
+				break;
+			case 0x2:
+				printf("5mA)\n");
+				break;
+			case 0x3:
+				printf("10mA)\n");
+				break;
+			case 0x4:
+				printf("25mA)\n");
+				break;
+			case 0x5:
+				printf("35mA)\n");
+				break;
+			case 0x6:
+				printf("60mA)\n");
+				break;
+			case 0x7:
+				printf("100mA)\n");
+				break;
+			}
+
+			printf("\tVDD_W_CURR_MAX: 0x%01x (", vdd_w_curr_max);
+			switch (vdd_w_curr_max) {
+			case 0x0:
+				printf("1mA)\n");
+				break;
+			case 0x1:
+				printf("5mA)\n");
+				break;
+			case 0x2:
+				printf("10mA)\n");
+				break;
+			case 0x3:
+				printf("25mA)\n");
+				break;
+			case 0x4:
+				printf("35mA)\n");
+				break;
+			case 0x5:
+				printf("45mA)\n");
+				break;
+			case 0x6:
+				printf("80mA)\n");
+				break;
+			case 0x7:
+				printf("200mA)\n");
+				break;
+			}
+
+			printf("\tC_SIZE_MULT: 0x%01x\n", c_size_mult);
+
+			mult = 1 << (c_size_mult + 2);
+			blocknr = (c_size + 1) * mult;
+			block_len = 1 << read_bl_len;
+			blocks = blocknr;
+			block_size = block_len;
+		} else if (csd_structure == 1) {
+			printf("\tC_SIZE: 0x%06x\n", c_size);
+
+			printf("\tERASE_BLK_EN: 0x%01x\n", erase_blk_en);
+			if (erase_blk_en != 0x01)
+				printf("Warn: Invalid ERASE_BLK_EN (should be 0x01)\n");
+
+			printf("\tSECTOR_SIZE: 0x%02x (Erasable sector: %d blocks)\n",
+			       sector_size, sector_size + 1);
+			if (sector_size != 0x7f)
+				printf("Warn: Invalid SECTOR_SIZE (should be 0x7f)\n");
+
+			printf("\tWP_GRP_SIZE: 0x%02x (Write protect group: %d blocks)\n",
+			       wp_grp_size, wp_grp_size + 1);
+			if (wp_grp_size != 0x00)
+				printf("Warn: Invalid WP_GRP_SIZE (should be 0x00)\n");
+
+			printf("\tWP_GRP_ENABLE: 0x%01x\n", wp_grp_enable);
+			if (wp_grp_enable != 0x00)
+				printf("Warn: Invalid WP_GRP_ENABLE (should be 0x00)\n");
+
+			printf("\tR2W_FACTOR: 0x%01x (Write %d times read)\n",
+			       r2w_factor, r2w_factor);
+			if (r2w_factor != 0x02)
+				printf("Warn: Invalid R2W_FACTOR (should be 0x02)\n");
+
+			printf("\tWRITE_BL_LEN: 0x%01x (", write_bl_len);
+			switch (write_bl_len) {
+			case 9:
+				printf("512 bytes)\n");
+				break;
+			case 10:
+				printf("1024 bytes)\n");
+				break;
+			case 11:
+				printf("2048 bytes)\n");
+				break;
+			default:
+				printf("reserved)\n");
+				break;
+			}
+
+			if (write_bl_len != 0x09)
+				printf("Warn: Invalid WRITE_BL_LEN (should be 0x09)\n");
+
+			printf("\tWRITE_BL_PARTIAL: 0x%01x\n", write_bl_partial);
+			if (write_bl_partial != 0x00)
+				printf("Warn: Invalid WRITE_BL_PARTIAL (should be 0x00)\n");
+
+			printf("\tFILE_FORMAT_GRP: 0x%01x\n", file_format_grp);
+			if (file_format_grp != 0x00)
+				printf("Warn: Invalid FILE_FORMAT_GRP (should be 0x00)\n");
+
+			printf("\tCOPY: 0x%01x\n", copy);
+			printf("\tPERM_WRITE_PROTECT: 0x%01x\n",
+			       perm_write_protect);
+			printf("\tTMP_WRITE_PROTECT: 0x%01x\n",
+			       tmp_write_protect);
+			printf("\tFILE_FORMAT: 0x%01x (",
+			       file_format);
+
+			if (file_format_grp == 1) {
+				printf("reserved)\n");
+			} else {
+				switch (file_format) {
+				case 0:
+					printf("partition table)\n");
+					break;
+				case 1:
+					printf("no partition table)\n");
+					break;
+				case 2:
+					printf("Universal File Format)\n");
+					break;
+				case 3:
+					printf("Others/unknown)\n");
+					break;
+				}
+			}
+
+			if (file_format != 0x00)
+				printf("Warn: Invalid FILE_FORMAT (should be 0x00)\n");
+
+			printf("\tCRC: 0x%01x\n", crc);
+
+			memory_capacity = (c_size + 1) * 512ull * 1024ull;
+			block_size = 512;
+			blocks = memory_capacity / block_size;
+		}
+
+		memory_capacity = blocks * block_size;
+
+		printf("\tCAPACITY: ");
+		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
+			printf("%.2fGbyte",
+			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull * 1024ull) > 0)
+			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull) > 0)
+			printf("%.2fKbyte", memory_capacity / (1024.0));
+		else
+			printf("%.2fbyte", memory_capacity * 1.0);
+
+		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
+		       memory_capacity, blocks, block_size);
+	} else {
+		unsigned long long blocks = 0;
+		int block_size = 0;
+		unsigned long long memory_capacity;
+
+		printf("card classes: ");
+		if (ccc & 0x800)
+			printf("11 extension, ");
+		if (ccc & 0x400)
+			printf("10 switch, ");
+		if (ccc & 0x200)
+			printf("9 I/O mode, ");
+		if (ccc & 0x100)
+			printf("8 application specific, ");
+		if (ccc & 0x080)
+			printf("7 lock card, ");
+		if (ccc & 0x040)
+			printf("6 write protection, ");
+		if (ccc & 0x020)
+			printf("5 erase, ");
+		if (ccc & 0x010)
+			printf("4 block write, ");
+		if (ccc & 0x008)
+			printf("3 reserved, ");
+		if (ccc & 0x004)
+			printf("2 block read, ");
+		if (ccc & 0x002)
+			printf("1 reserved, ");
+		if (ccc & 0x001)
+			printf("0 basic, ");
+		printf("\b\b\n");
+
+		if (csd_structure == 0) {
+			int mult;
+			int blocknr;
+			int block_len;
+
+			mult = 1 << (c_size_mult + 2);
+			blocknr = (c_size + 1) * mult;
+			block_len = 1 << read_bl_len;
+			blocks = blocknr;
+			block_size = block_len;
+		} else if (csd_structure == 1) {
+			memory_capacity = (c_size + 1) * 512ull * 1024ull;
+			block_size = 512;
+			blocks = memory_capacity / block_size;
+		}
+
+		memory_capacity = blocks * block_size;
+
+		printf("capacity: ");
+		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
+			printf("%.2fGbyte",
+			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull * 1024ull) > 0)
+			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull) > 0)
+			printf("%.2fKbyte", memory_capacity / (1024.0));
+		else
+			printf("%.2fbyte", memory_capacity * 1.0);
+
+		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
+		       memory_capacity, blocks, block_size);
+	}
+}
+
+void print_mmc_csd(struct config *config, char *csd)
+{
+	unsigned int csd_structure;
+	unsigned int spec_vers;
+	unsigned int taac_timevalue;
+	unsigned int taac_timeunit;
+	unsigned int nsac;
+	unsigned int tran_speed_timevalue;
+	unsigned int tran_speed_transferrateunit;
+	unsigned int ccc;
+	unsigned int read_bl_len;
+	unsigned int read_bl_partial;
+	unsigned int write_blk_misalign;
+	unsigned int read_blk_misalign;
+	unsigned int dsr_imp;
+	unsigned int c_size;
+	unsigned int vdd_r_curr_min;
+	unsigned int vdd_r_curr_max;
+	unsigned int vdd_w_curr_min;
+	unsigned int vdd_w_curr_max;
+	unsigned int c_size_mult;
+	unsigned int erase_grp_size;
+	unsigned int erase_grp_mult;
+	unsigned int wp_grp_size;
+	unsigned int wp_grp_enable;
+	unsigned int default_ecc;
+	unsigned int r2w_factor;
+	unsigned int write_bl_len;
+	unsigned int write_bl_partial;
+	unsigned int content_prot_app;
+	unsigned int file_format_grp;
+	unsigned int copy;
+	unsigned int perm_write_protect;
+	unsigned int tmp_write_protect;
+	unsigned int file_format;
+	unsigned int ecc;
+	unsigned int crc;
+	unsigned int taac;
+	unsigned int tran_speed;
+
+	parse_bin(csd, "2u4u2r1r4u3u8u1r4u3u12u4u1u1u1u1u2r12u3u3u3u3u3u"
+		  "5u5u5u1u2u3u4u1u4r1u1u1u1u1u2u2u7u1r",
+		  &csd_structure, &spec_vers, &taac_timevalue,
+		  &taac_timeunit, &nsac, &tran_speed_timevalue,
+		  &tran_speed_transferrateunit, &ccc, &read_bl_len,
+		  &read_bl_partial, &write_blk_misalign,
+		  &read_blk_misalign, &dsr_imp, &c_size,
+		  &vdd_r_curr_min, &vdd_r_curr_max,
+		  &vdd_w_curr_min, &vdd_w_curr_max, &c_size_mult,
+		  &erase_grp_size, &erase_grp_mult, &wp_grp_size,
+		  &wp_grp_enable, &default_ecc, &r2w_factor,
+		  &write_bl_len, &write_bl_partial, &content_prot_app,
+		  &file_format_grp, &copy, &perm_write_protect,
+		  &tmp_write_protect, &file_format, &ecc, &crc);
+
+	taac = taac_timevalue << 3 | taac_timeunit;
+	tran_speed = tran_speed_timevalue << 3 | tran_speed_transferrateunit;
+
+	if (config->verbose) {
+		float value;
+		int mult;
+		int blocknr;
+		int block_len;
+		unsigned long long blocks = 0;
+		int block_size = 0;
+		unsigned long long memory_capacity;
+
+		printf("======MMC/CSD======\n");
+
+		printf("\tCSD_STRUCTURE: 0x%01x (", csd_structure);
+		switch (csd_structure) {
+		case 0x0:
+			printf("v1.0)\n");
+			break;
+		case 0x1:
+			printf("v1.1)\n");
+			break;
+		case 0x2:
+			printf("v1.2)\n");
+			break;
+		case 0x3:
+			printf("version in ext_csd)\n");
+			break;
+		}
+
+		printf("\tSPEC_VERS: 0x%01x (", spec_vers);
+		switch (spec_vers) {
+		case 0x0:
+			printf("v1.0-v1.2)\n");
+			break;
+		case 0x1:
+			printf("v1.4)\n");
+			break;
+		case 0x2:
+			printf("v2.0-v2.2)\n");
+			break;
+		case 0x3:
+			printf("v3.1-v3.31)\n");
+			break;
+		case 0x4:
+			printf("v4.0-v4.3)\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tTAAC: 0x%02x (", taac);
+		switch (taac_timevalue) {
+		case 0x0:
+			value = 0.0f;
+			break;
+		case 0x1:
+			value = 1.0f;
+			break;
+		case 0x2:
+			value = 1.2f;
+			break;
+		case 0x3:
+			value = 1.3f;
+			break;
+		case 0x4:
+			value = 1.5f;
+			break;
+		case 0x5:
+			value = 2.0f;
+			break;
+		case 0x6:
+			value = 2.5f;
+			break;
+		case 0x7:
+			value = 3.0f;
+			break;
+		case 0x8:
+			value = 3.5f;
+			break;
+		case 0x9:
+			value = 4.0f;
+			break;
+		case 0xa:
+			value = 4.5f;
+			break;
+		case 0xb:
+			value = 5.0f;
+			break;
+		case 0xc:
+			value = 5.5f;
+			break;
+		case 0xd:
+			value = 6.0f;
+			break;
+		case 0xe:
+			value = 7.0f;
+			break;
+		case 0xf:
+			value = 8.0f;
+			break;
+		default:
+			value = 0.0f;
+			break;
+		}
+
+		switch (taac_timeunit) {
+		case 0x0:
+			printf("%.2fns)\n", value * 1.0f);
+			break;
+		case 0x1:
+			printf("%.2fns)\n", value * 10.0f);
+			break;
+		case 0x2:
+			printf("%.2fns)\n", value * 100.0f);
+			break;
+		case 0x3:
+			printf("%.2fus)\n", value * 1.0f);
+			break;
+		case 0x4:
+			printf("%.2fus)\n", value * 10.0f);
+			break;
+		case 0x5:
+			printf("%.2fus)\n", value * 100.0f);
+			break;
+		case 0x6:
+			printf("%.2fms)\n", value * 1.0f);
+			break;
+		case 0x7:
+			printf("%.2fms)\n", value * 10.0f);
+			break;
+		}
+
+		printf("\tNSAC: %d clocks\n", nsac);
+		printf("\tTRAN_SPEED: 0x%02x (", tran_speed);
+		switch (tran_speed_timevalue) {
+		case 0x0:
+			value = 0.0f;
+			break;
+		case 0x1:
+			value = 1.0f;
+			break;
+		case 0x2:
+			value = 1.2f;
+			break;
+		case 0x3:
+			value = 1.3f;
+			break;
+		case 0x4:
+			value = 1.5f;
+			break;
+		case 0x5:
+			value = 2.0f;
+			break;
+		case 0x6:
+			value = 2.6f;
+			break;
+		case 0x7:
+			value = 3.0f;
+			break;
+		case 0x8:
+			value = 3.5f;
+			break;
+		case 0x9:
+			value = 4.0f;
+			break;
+		case 0xa:
+			value = 4.5f;
+			break;
+		case 0xb:
+			value = 5.2f;
+			break;
+		case 0xc:
+			value = 5.5f;
+			break;
+		case 0xd:
+			value = 6.0f;
+			break;
+		case 0xe:
+			value = 7.0f;
+			break;
+		case 0xf:
+			value = 8.0f;
+			break;
+		default:
+			value = 0.0f;
+			break;
+		}
+
+		switch (tran_speed_transferrateunit) {
+		case 0x0:
+			printf("%.2fKHz/s)\n", value * 100.0f);
+			break;
+		case 0x1:
+			printf("%.2fMHz/s)\n", value * 1.0f);
+			break;
+		case 0x2:
+			printf("%.2fMHz/s)\n", value * 10.0f);
+			break;
+		case 0x3:
+			printf("%.2fMHz/s)\n", value * 100.0f);
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tCCC: 0x%03x (class: ", ccc);
+		if (ccc & 0x800)
+			printf("11, ");
+		if (ccc & 0x400)
+			printf("10, ");
+		if (ccc & 0x200)
+			printf("9, ");
+		if (ccc & 0x100)
+			printf("8, ");
+		if (ccc & 0x080)
+			printf("7, ");
+		if (ccc & 0x040)
+			printf("6, ");
+		if (ccc & 0x020)
+			printf("5, ");
+		if (ccc & 0x010)
+			printf("4, ");
+		if (ccc & 0x008)
+			printf("3, ");
+		if (ccc & 0x004)
+			printf("2, ");
+		if (ccc & 0x002)
+			printf("1, ");
+		if (ccc & 0x001)
+			printf("0, ");
+		printf("  )\n");
+
+		printf("\tREAD_BL_LEN: 0x%01x (", read_bl_len);
+		switch (read_bl_len) {
+		case 0x0:
+			printf("1 byte)\n");
+			break;
+		case 0x1:
+			printf("2 byte)\n");
+			break;
+		case 0x2:
+			printf("4 byte)\n");
+			break;
+		case 0x3:
+			printf("8 byte)\n");
+			break;
+		case 0x4:
+			printf("16 byte)\n");
+			break;
+		case 0x5:
+			printf("32 byte)\n");
+			break;
+		case 0x6:
+			printf("64 byte)\n");
+			break;
+		case 0x7:
+			printf("128 byte)\n");
+			break;
+		case 0x8:
+			printf("256 byte)\n");
+			break;
+		case 0x9:
+			printf("512 bytes)\n");
+			break;
+		case 0xa:
+			printf("1024 bytes)\n");
+			break;
+		case 0xb:
+			printf("2048 bytes)\n");
+			break;
+		case 0xc:
+			printf("4096 bytes)\n");
+			break;
+		case 0xd:
+			printf("8192 bytes)\n");
+			break;
+		case 0xe:
+			printf("16K bytes)\n");
+			break;
+		default:
+			printf("reserved bytes)\n");
+			break;
+		}
+
+		printf("\tREAD_BL_PARTIAL: 0x%01x (", read_bl_partial);
+		switch (read_bl_partial) {
+		case 0x0:
+			printf("only 512 byte and READ_BL_LEN block size)\n");
+			break;
+		case 0x1:
+			printf("less than READ_BL_LEN block size can be used)\n");
+			break;
+		}
+
+		printf("\tWRITE_BLK_MISALIGN: 0x%01x (", write_blk_misalign);
+		switch (write_blk_misalign) {
+		case 0x0:
+			printf("writes across block boundaries are invalid)\n");
+			break;
+		case 0x1:
+			printf("writes across block boundaries are allowed)\n");
+			break;
+		}
+
+		printf("\tREAD_BLK_MISALIGN: 0x%01x (", read_blk_misalign);
+		switch (read_blk_misalign) {
+		case 0x0:
+			printf("reads across block boundaries are invalid)\n");
+			break;
+		case 0x1:
+			printf("reads across block boundaries are allowed)\n");
+			break;
+		}
+
+		printf("\tDSR_IMP: 0x%01x (", dsr_imp);
+		switch (dsr_imp) {
+		case 0x0:
+			printf("configurable driver stage not available)\n");
+			break;
+		case 0x1:
+			printf("configurable driver state available)\n");
+			break;
+		}
+
+		printf("\tC_SIZE: 0x%03x\n", c_size);
+		printf("\tVDD_R_CURR_MIN: 0x%01x (", vdd_r_curr_min);
+		switch (vdd_r_curr_min) {
+		case 0x0:
+			printf("0.5mA)\n");
+			break;
+		case 0x1:
+			printf("1mA)\n");
+			break;
+		case 0x2:
+			printf("5mA)\n");
+			break;
+		case 0x3:
+			printf("10mA)\n");
+			break;
+		case 0x4:
+			printf("25mA)\n");
+			break;
+		case 0x5:
+			printf("35mA)\n");
+			break;
+		case 0x6:
+			printf("60mA)\n");
+			break;
+		case 0x7:
+			printf("100mA)\n");
+			break;
+		}
+
+		printf("\tVDD_R_CURR_MAX: 0x%01x (", vdd_r_curr_max);
+		switch (vdd_r_curr_max) {
+		case 0x0:
+			printf("1mA)\n");
+			break;
+		case 0x1:
+			printf("5mA)\n");
+			break;
+		case 0x2:
+			printf("10mA)\n");
+			break;
+		case 0x3:
+			printf("25mA)\n");
+			break;
+		case 0x4:
+			printf("35mA)\n");
+			break;
+		case 0x5:
+			printf("45mA)\n");
+			break;
+		case 0x6:
+			printf("80mA)\n");
+			break;
+		case 0x7:
+			printf("200mA)\n");
+			break;
+		}
+
+		printf("\tVDD_W_CURR_MIN: 0x%01x (", vdd_w_curr_min);
+		switch (vdd_w_curr_min) {
+		case 0x0:
+			printf("0.5mA)\n");
+			break;
+		case 0x1:
+			printf("1mA)\n");
+			break;
+		case 0x2:
+			printf("5mA)\n");
+			break;
+		case 0x3:
+			printf("10mA)\n");
+			break;
+		case 0x4:
+			printf("25mA)\n");
+			break;
+		case 0x5:
+			printf("35mA)\n");
+			break;
+		case 0x6:
+			printf("60mA)\n");
+			break;
+		case 0x7:
+			printf("100mA)\n");
+			break;
+		}
+
+		printf("\tVDD_W_CURR_MAX: 0x%01x (", vdd_w_curr_max);
+		switch (vdd_w_curr_max) {
+		case 0x0:
+			printf("1mA)\n");
+			break;
+		case 0x1:
+			printf("5mA)\n");
+			break;
+		case 0x2:
+			printf("10mA)\n");
+			break;
+		case 0x3:
+			printf("25mA)\n");
+			break;
+		case 0x4:
+			printf("35mA)\n");
+			break;
+		case 0x5:
+			printf("45mA)\n");
+			break;
+		case 0x6:
+			printf("80mA)\n");
+			break;
+		case 0x7:
+			printf("200mA)\n");
+			break;
+		}
+
+		printf("\tC_SIZE_MULT: 0x%01x\n", c_size_mult);
+		printf("\tERASE_GRP_SIZE: 0x%02x\n", erase_grp_size);
+		printf("\tERASE_GRP_MULT: 0x%02x (%d write blocks/erase group)\n",
+		       erase_grp_mult, (erase_grp_size + 1) *
+		       (erase_grp_mult + 1));
+		printf("\tWP_GRP_SIZE: 0x%02x (%d blocks/write protect group)\n",
+		       wp_grp_size, wp_grp_size + 1);
+		printf("\tWP_GRP_ENABLE: 0x%01x\n", wp_grp_enable);
+
+		printf("\tDEFAULT_ECC: 0x%01x (", default_ecc);
+		switch (default_ecc) {
+		case 0:
+			printf("none)\n");
+			break;
+		case 1:
+			printf("BCH)\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tR2W_FACTOR: 0x%01x (Write %d times read)\n",
+		       r2w_factor, r2w_factor);
+
+		printf("\tWRITE_BL_LEN: 0x%01x (", write_bl_len);
+		switch (write_bl_len) {
+		case 0x0:
+			printf("1 byte)\n");
+			break;
+		case 0x1:
+			printf("2 byte)\n");
+			break;
+		case 0x2:
+			printf("4 byte)\n");
+			break;
+		case 0x3:
+			printf("8 byte)\n");
+			break;
+		case 0x4:
+			printf("16 byte)\n");
+			break;
+		case 0x5:
+			printf("32 byte)\n");
+			break;
+		case 0x6:
+			printf("64 byte)\n");
+			break;
+		case 0x7:
+			printf("128 byte)\n");
+			break;
+		case 0x8:
+			printf("256 byte)\n");
+			break;
+		case 0x9:
+			printf("512 bytes)\n");
+			break;
+		case 0xa:
+			printf("1024 bytes)\n");
+			break;
+		case 0xb:
+			printf("2048 bytes)\n");
+			break;
+		case 0xc:
+			printf("4096 bytes)\n");
+			break;
+		case 0xd:
+			printf("8192 bytes)\n");
+			break;
+		case 0xe:
+			printf("16K bytes)\n");
+			break;
+		default:
+			printf("reserved bytes)\n");
+			break;
+		}
+
+		printf("\tWRITE_BL_PARTIAL: 0x%01x (", write_bl_partial);
+		switch (write_bl_partial) {
+		case 0x0:
+			printf("only 512 byte and WRITE_BL_LEN block size)\n");
+			break;
+		case 0x1:
+			printf("less than WRITE_BL_LEN block size can be used)\n");
+			break;
+		}
+
+		printf("\tCONTENT_PROT_APP: 0x%01x\n", content_prot_app);
+		printf("\tFILE_FORMAT_GRP: 0x%01x\n", file_format_grp);
+		if (file_format_grp != 0)
+			printf("Warn: Invalid FILE_FORMAT_GRP\n");
+
+		printf("\tCOPY: 0x%01x\n", copy);
+		printf("\tPERM_WRITE_PROTECT: 0x%01x\n", perm_write_protect);
+		printf("\tTMP_WRITE_PROTECT: 0x%01x\n", tmp_write_protect);
+		printf("\tFILE_FORMAT: 0x%01x (", file_format);
+		if (file_format != 0)
+			printf("Warn: Invalid FILE_FORMAT\n");
+
+		if (file_format_grp == 1) {
+			printf("reserved)\n");
+		} else {
+			switch (file_format) {
+			case 0:
+				printf("partition table)\n");
+				break;
+			case 1:
+				printf("no partition table)\n");
+				break;
+			case 2:
+				printf("Universal File Format)\n");
+				break;
+			case 3:
+				printf("Others/unknown)\n");
+				break;
+			}
+		}
+
+		printf("\tECC: 0x%01x (", ecc);
+		switch (ecc) {
+		case 0:
+			printf("none)\n");
+			break;
+		case 1:
+			printf("BCH(542,512))\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tCRC: 0x%01x\n", crc);
+
+		mult = 1 << (c_size_mult + 2);
+		blocknr = (c_size + 1) * mult;
+		block_len = 1 << read_bl_len;
+		blocks = blocknr;
+		block_size = block_len;
+
+		memory_capacity = blocks * block_size;
+
+		printf("\tCAPACITY: ");
+		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
+			printf("%.2fGbyte",
+			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull * 1024ull) > 0)
+			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull) > 0)
+			printf("%.2fKbyte", memory_capacity / (1024.0));
+		else
+			printf("%.2fbyte", memory_capacity * 1.0);
+
+		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
+		       memory_capacity, blocks, block_size);
+	} else {
+		int mult;
+		int blocknr;
+		int block_len;
+		unsigned long long blocks = 0;
+		int block_size = 0;
+		unsigned long long memory_capacity;
+
+		printf("version: ");
+		switch (spec_vers) {
+		case 0x0:
+			printf("MMC v1.0-v1.2\n");
+			break;
+		case 0x1:
+			printf("MMC v1.4\n");
+			break;
+		case 0x2:
+			printf("MMC v2.0-v2.2\n");
+			break;
+		case 0x3:
+			printf("MMC v3.1-v3.31\n");
+			break;
+		case 0x4:
+			printf("MMC v4.0-v4.3\n");
+			break;
+		default:
+			printf("reserved\n");
+			break;
+		}
+
+		printf("card classes: ");
+		if (ccc & 0x800)
+			printf("11, ");
+		if (ccc & 0x400)
+			printf("10, ");
+		if (ccc & 0x200)
+			printf("9, ");
+		if (ccc & 0x100)
+			printf("8, ");
+		if (ccc & 0x080)
+			printf("7, ");
+		if (ccc & 0x040)
+			printf("6, ");
+		if (ccc & 0x020)
+			printf("5, ");
+		if (ccc & 0x010)
+			printf("4, ");
+		if (ccc & 0x008)
+			printf("3, ");
+		if (ccc & 0x004)
+			printf("2, ");
+		if (ccc & 0x002)
+			printf("1, ");
+		if (ccc & 0x001)
+			printf("0, ");
+		printf("\b\b\n");
+
+		mult = 1 << (c_size_mult + 2);
+		blocknr = (c_size + 1) * mult;
+		block_len = 1 << read_bl_len;
+		blocks = blocknr;
+		block_size = block_len;
+
+		memory_capacity = blocks * block_size;
+
+		printf("capacity: ");
+		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
+			printf("%.2fGbyte",
+			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull * 1024ull) > 0)
+			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
+		else if (memory_capacity / (1024ull) > 0)
+			printf("%.2fKbyte", memory_capacity / (1024.0));
+		else
+			printf("%.2fbyte", memory_capacity * 1.0);
+		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
+		       memory_capacity, blocks, block_size);
+	}
+}
+
+char *speed_class_speed(unsigned char id, bool ddr)
+{
+	if (ddr) {
+		switch (id) {
+		case 0x00: return "<4.8MB/s";
+		case 0x08: return " 4.8MB/s";
+		case 0x0a: return " 6.0MB/s";
+		case 0x0f: return " 9.0MB/s";
+		case 0x14: return "12.0MB/s";
+		case 0x1e: return "18.0MB/s";
+		case 0x28: return "24.0MB/s";
+		case 0x32: return "30.0MB/s";
+		case 0x3c: return "36.0MB/s";
+		case 0x46: return "42.0MB/s";
+		case 0x50: return "48.0MB/s";
+		case 0x64: return "60.0MB/s";
+		case 0x78: return "72.0MB/s";
+		case 0x8c: return "84.0MB/s";
+		case 0xa0: return "96.0MB/s";
+		default: return "??.?MB/s";
+		}
+	} else {
+		switch (id) {
+		case 0x00: return "<2.4MB/s";
+		case 0x08: return " 2.4MB/s";
+		case 0x0a: return " 3.0MB/s";
+		case 0x0f: return " 4.5MB/s";
+		case 0x14: return " 6.0MB/s";
+		case 0x1e: return " 9.0MB/s";
+		case 0x28: return "12.0MB/s";
+		case 0x32: return "15.0MB/s";
+		case 0x3c: return "18.0MB/s";
+		case 0x46: return "21.0MB/s";
+		case 0x50: return "24.0MB/s";
+		case 0x64: return "30.0MB/s";
+		case 0x78: return "36.0MB/s";
+		case 0x8c: return "42.0MB/s";
+		case 0xa0: return "48.0MB/s";
+		default: return "??.?MB/s";
+		}
+	}
+}
+
+char speed_class_name(unsigned char id)
+{
+	switch (id) {
+	case 0x00: return '?';
+	case 0x08: return 'A';
+	case 0x0a: return 'B';
+	case 0x0f: return 'C';
+	case 0x14: return 'D';
+	case 0x1e: return 'E';
+	case 0x28: return 'F';
+	case 0x32: return 'G';
+	case 0x3c: return 'H';
+	case 0x46: return 'J';
+	case 0x50: return 'K';
+	case 0x64: return 'M';
+	case 0x78: return 'O';
+	case 0x8c: return 'R';
+	case 0xa0: return 'T';
+	default: return '?';
+	}
+}
+
+char *power_class_consumption(unsigned int id, bool volt360)
+{
+	if (volt360) {
+		switch (id) {
+		case 0x0: return "100-200mA";
+		case 0x1: return "120-220mA";
+		case 0x2: return "150-250mA";
+		case 0x3: return "180-280mA";
+		case 0x4: return "200-300mA";
+		case 0x5: return "220-320mA";
+		case 0x6: return "250-350mA";
+		case 0x7: return "300-400mA";
+		case 0x8: return "350-450mA";
+		case 0x9: return "400-500mA";
+		case 0xa: return "450-550mA";
+		default: return "reserved";
+		}
+	} else {
+		switch (id) {
+		case 0x0: return "65-130mA";
+		case 0x1: return "70-140mA";
+		case 0x2: return "80-160mA";
+		case 0x3: return "90-180mA";
+		case 0x4: return "100-200mA";
+		case 0x5: return "120-220mA";
+		case 0x6: return "140-240mA";
+		case 0x7: return "160-260mA";
+		case 0x8: return "180-280mA";
+		case 0x9: return "200-300mA";
+		case 0xa: return "250-350mA";
+		default: return "reserved";
+		}
+	}
+}
+
+char *sleep_consumption(unsigned int id)
+{
+	switch (id) {
+	case 0x00: return "not defined";
+	case 0x01: return "2uA";
+	case 0x02: return "4uA";
+	case 0x03: return "8uA";
+	case 0x04: return "16uA";
+	case 0x05: return "32uA";
+	case 0x06: return "64uA";
+	case 0x07: return "128uA";
+	case 0x08: return "0.256mA";
+	case 0x09: return "0.512mA";
+	case 0x0a: return "1.024mA";
+	case 0x0b: return "2.048mA";
+	case 0x0c: return "4.096mA";
+	case 0x0d: return "8.192mA";
+	default: return "reserved";
+	}
+}
+
+void print_sd_scr(struct config *config, char *scr)
+{
+	unsigned int scr_structure;
+	unsigned int sd_spec;
+	unsigned int data_stat_after_erase;
+	unsigned int sd_security;
+	unsigned int sd_bus_widths;
+	unsigned int sd_spec3;
+	unsigned int ex_security;
+	unsigned int cmd_support;
+
+	parse_bin(scr, "4u4u1u3u4u1u4u9r2u32r",
+		&scr_structure, &sd_spec, &data_stat_after_erase,
+		&sd_security, &sd_bus_widths, &sd_spec3,
+		&ex_security, &cmd_support);
+
+	if (config->verbose) {
+		printf("======SD/SCR======\n");
+
+		printf("\tSCR_STRUCTURE: 0x%01x (", scr_structure);
+		switch (scr_structure) {
+		case 0:
+			printf("SCR v1.0)\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tSD_SPEC: 0x%01x (", sd_spec);
+		switch (sd_spec) {
+		case 0:
+			printf("SD v1.0/1.01)\n");
+			break;
+		case 1:
+			printf("SD v1.10)\n");
+			break;
+		case 2:
+			printf("SD v2.00/v3.0x)\n");
+			break;
+		case 3:
+			printf("SD v4.00)\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tDATA_STAT_AFTER_ERASE: 0x%01x\n",
+		       data_stat_after_erase);
+
+		printf("\tSD_SECURITY: 0x%01x (", sd_security);
+		switch (sd_security) {
+		case 0:
+			printf("no security)\n");
+			break;
+		case 1:
+			printf("not used)\n");
+			break;
+		case 2:
+			printf("SDSC card/security v1.01)\n");
+			break;
+		case 3:
+			printf("SDHC card/security v2.00)\n");
+			break;
+		case 4:
+			printf("SDXC card/security v3.xx)\n");
+			break;
+		default:
+			printf("reserved)\n");
+			break;
+		}
+
+		printf("\tSD_BUS_WIDTHS: 0x%01x (", sd_bus_widths);
+		if (BITS(sd_bus_widths, 2, 2))
+			printf("4bit, ");
+		if (BITS(sd_bus_widths, 0, 0))
+			printf("1bit, ");
+		printf(" bus)\n");
+
+		printf("\tSD_SPEC3: 0x%01x (", sd_spec3);
+		if (sd_spec >= 2) {
+			switch (sd_spec3) {
+			case 0:
+				printf("SD v2.00)\n");
+				break;
+			case 1:
+				printf("SD v3.0x)\n");
+				break;
+			}
+		} else {
+			printf("SD 1.xx)\n");
+		}
+
+		printf("\tEX_SECURITY: 0x%01x\n", ex_security);
+
+		printf("\tCMD_SUPPORT: 0x%01x (", cmd_support);
+		if (BITS(cmd_support, 1, 1))
+			printf("CMD23 ");
+		if (BITS(cmd_support, 0, 0))
+			printf("CMD20 ");
+		printf(" )\n");
+	} else {
+		printf("version: ");
+		switch (sd_spec) {
+		case 0:
+			printf("SD 1.0/1.01\n");
+			break;
+		case 1:
+			printf("SD 1.10\n");
+			break;
+		case 2:
+			switch (sd_spec3) {
+			case 0:
+				printf("SD 2.00\n");
+				break;
+			case 1:
+				printf("SD 3.0x\n");
+				break;
+			default:
+				printf("unknown\n");
+				break;
+			}
+			break;
+		case 3:
+			printf("SD 4.00\n");
+			break;
+		default:
+			printf("unknown\n");
+			break;
+		}
+
+		printf("bus widths: ");
+		if (BITS(sd_bus_widths, 2, 2))
+			printf("4bit, ");
+		if (BITS(sd_bus_widths, 0, 0))
+			printf("1bit, ");
+		printf("\b\b\n");
+	}
+}
+
+/* MMC/SD interface processing functions */
+void print_info(struct config *config, char *type,
+	char *cid, char *csd, char *scr, char *ext_csd)
+{
+	printf("type: '%s'\n", type);
+
+	if (!strcmp(type, "SD") && cid)
+		print_sd_cid(config, cid);
+	else if (!strcmp(type, "MMC") && cid)
+		print_mmc_cid(config, cid);
+
+	if (!strcmp(type, "SD") && scr)
+		print_sd_scr(config, scr);
+
+	if (!strcmp(type, "MMC") && csd)
+		print_mmc_csd(config, csd);
+	else if (!strcmp(type, "SD") && csd)
+		print_sd_csd(config, csd);
+}
+
+int process_dir(struct config *config, enum REG_TYPE reg)
+{
+	char *type = NULL, *cid = NULL, *csd = NULL, *scr = NULL, *ext_csd = NULL;
+	int ret = 0;
+
+	if (chdir(config->dir) < 0) {
+		fprintf(stderr,
+			"MMC/SD information directory '%s' does not exist.\n",
+			config->dir);
+		return -1;
+	}
+
+	type = read_file("type");
+	if (!type) {
+		fprintf(stderr,
+			"Could not read card interface type in directory '%s'.\n",
+			config->dir);
+		return -1;
+	}
+
+	if (strcmp(type, "MMC") && strcmp(type, "SD")) {
+		fprintf(stderr, "Unknown type: '%s'\n", type);
+		ret = -1;
+		goto err;
+	}
+
+	switch (reg) {
+	case CID:
+		cid = read_file("cid");
+		if (!cid) {
+			fprintf(stderr,
+				"Could not read card identity in directory '%s'.\n",
+				config->dir);
+			ret = -1;
+			goto err;
+		}
+		break;
+	case CSD:
+		csd = read_file("csd");
+		if (!csd) {
+			fprintf(stderr,
+				"Could not read card specific data in "
+				"directory '%s'.\n", config->dir);
+			ret = -1;
+			goto err;
+		}
+		break;
+	case SCR:
+		if (!strcmp(type, "SD")) {
+			scr = read_file("scr");
+			if (!scr) {
+				fprintf(stderr, "Could not read SD card "
+					"configuration in directory '%s'.\n",
+					config->dir);
+				ret = -1;
+				goto err;
+			}
+		}
+		break;
+	case EXT_CSD:
+		if (!strcmp(type, "MMC")) {
+			ext_csd = read_file("ext_csd");
+			if (!ext_csd) {
+				fprintf(stderr, "Could not read extra specific "
+					"data in directory '%s'.\n",
+					config->dir);
+				ret = -1;
+				goto err;
+			}
+		}
+		break;
+	default:
+		goto err;
+	}
+
+	print_info(config, type, cid, csd, scr, ext_csd);
+
+err:
+	free(ext_csd);
+	free(scr);
+	free(csd);
+	free(cid);
+	free(type);
+
+	return ret;
+}
+
+int lsmmc_main(struct config *config, int argc, char **argv)
+{
+	int ret;
+
+	memset(config, 0, sizeof(*config));
+	config->mmc_ids = calloc(IDS_MAX, sizeof(char *));
+	config->sd_ids = calloc(IDS_MAX, sizeof(char *));
+	if (!config->mmc_ids || !config->sd_ids) {
+		fprintf(stderr, "Could not allocate memory for lsmmc.\n");
+		return -1;
+	}
+
+	ret = parse_opts(argc, argv, config);
+	if (ret)
+		return ret;
+
+	return parse_ids(config);
+}
+
+void lsmmc_free(struct config *config)
+{
+	free(config->mmc_ids);
+	free(config->sd_ids);
+	free(config->dir);
+}
+
+int do_read_csd(int argc, char **argv)
+{
+	struct config config;
+	int ret;
+
+	if (argc != 2 && argc != 3) {
+		fprintf(stderr, "Usage: Print CSD data from <device path>.\n");
+		exit(1);
+	}
+
+	ret = lsmmc_main(&config, argc, argv);
+	if (ret)
+		goto out;
+
+	if (config.dir)
+		ret = process_dir(&config, CSD);
+
+out:
+	lsmmc_free(&config);
+
+	return ret;
+}
+
+int do_read_cid(int argc, char **argv)
+{
+	struct config config;
+	int ret;
+
+	if (argc != 2 && argc != 3) {
+		fprintf(stderr, "Usage: Print CID data from <device path>.\n");
+		exit(1);
+	}
+
+	ret = lsmmc_main(&config, argc, argv);
+	if (ret)
+		goto out;
+
+	if (config.dir)
+		ret = process_dir(&config, CID);
+
+out:
+	lsmmc_free(&config);
+
+	return ret;
+}
+
+int do_read_scr(int argc, char **argv)
+{
+	struct config config;
+	int ret;
+
+	if (argc != 2 && argc != 3) {
+		fprintf(stderr, "Usage: Print SCR data from <device path>.\n");
+		exit(1);
+	}
+
+	ret = lsmmc_main(&config, argc, argv);
+	if (ret)
+		goto out;
+
+	if (config.dir)
+		ret = process_dir(&config, SCR);
+
+out:
+	lsmmc_free(&config);
+
+	return ret;
+}

+ 5 - 0
emmc_hal_lib/mmc-utils/man/Makefile

@@ -0,0 +1,5 @@
+all: 
+clean: 
+install:
+
+.PHONY: all clean install

+ 125 - 0
emmc_hal_lib/mmc-utils/man/mmc.1

@@ -0,0 +1,125 @@
+.TH MMC 1 "2015-11-16" "0.1" "mmc-utils"
+.SH
+NAME
+mmc-utils \- Configure MMC storage devices from userspace.
+.SH
+SYNOPSIS
+mmc [<command> [<args>]] [--help]
+.PP
+mmc [<command>] --help
+.SH
+DESCRIPTION
+mmc-utils is a tool for configuring MMC storage devices from userspace.
+.SH
+COMMANDS AND OPTIONS
+.TP
+.BR "help | \-\-help | -h | " "(no arguments)"
+Shows the abbreviated help menu in the terminal.
+.TP
+.BR "extcsd read <device>"
+Print extcsd data from <device>.
+.TP
+.BR "writeprotect get <device>"
+Determine the eMMC writeprotect status of <device>.
+.TP
+.BR "writeprotect set <device>"
+Set the eMMC writeprotect status of <device>.
+This sets the eMMC to be write-protected until next boot.
+.TP
+.BR "disable 512B emulation <device>"
+Set the eMMC data sector size to 4KB by disabling emulation on
+<device>.
+.TP
+.BR "gp create <-y|-n> <length KiB> <partition> <enh_attr> <ext_attr> <device>"
+create general purpose partition for the <device>.
+Dry-run only unless -y is passed.
+To set enhanced attribute to general partition being created set <enh_attr> to 1 else set it to 0.
+To set extended attribute to general partition set <ext_attr> to 1,2 else set it to 0.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "enh_area set <-y|-n> <start KiB> <length KiB> <device>"
+Enable the enhanced user area for the <device>.
+Dry-run only unless -y is passed.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "write_reliability set <-y|-n> <partition> <device>"
+Enable write reliability per partition for the <device>.
+Dry-run only unless -y is passed.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "status get <device>"
+Print the response to STATUS_SEND (CMD13).
+.TP
+.BR "bootpart enable <boot_partition> <send_ack> <device>"
+Enable the boot partition for the <device>.
+Disable the boot partition for the <device> with <boot_partition> set to 0.
+To receive acknowledgment of boot from the card set <send_ack>
+to 1, else set it to 0.
+.TP
+.BR "bootbus set <boot_mode> <reset_boot_bus_conditions> <boot_bus_width> <device>"
+Set Boot Bus Conditions.
+<boot_mode> must be "single_backward|single_hs|dual"
+<reset_boot_bus_conditions> must be "x1|retain"
+<boot_bus_width> must be "x1|x4|x8"
+.TP
+.BR "bkops enable <device>"
+Enable the eMMC BKOPS feature on <device>.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "hwreset enable <device>"
+Permanently enable the eMMC H/W Reset feature on <device>.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "hwreset disable <device>"
+Permanently disable the eMMC H/W Reset feature on <device>.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "sanitize <device>"
+Send Sanitize command to the <device>.
+This will delete the unmapped memory region of the device.
+.TP
+.BR "rpmb write-key <rpmb device> <key file>"
+Program authentication key which is 32 bytes length and stored
+in the specified file. Also you can specify '-' instead of
+key file path to read the key from stdin.
+NOTE!  This is a one-time programmable (unreversible) change.
+.TP
+.BR "rpmb read-counter <rpmb device>"
+Counter value for the <rpmb device> will be read to stdout.
+.TP
+.BR "rpmb read-block <rpmb device> <address> <blocks count> <output file> [key file]"
+Blocks of 256 bytes will be read from <rpmb device> to output
+file or stdout if '-' is specified. If key is specified - read
+data will be verified. Instead of regular path you can specify
+'-' to read key from stdin.
+.TP
+.BR "rpmb write-block <rpmb device> <address> <256 byte data file> <key file>"
+Block of 256 bytes will be written from data file to
+<rpmb device>. Also you can specify '-' instead of key
+file path or data file to read the data from stdin.
+.TP
+.BR "cache enable <device>"
+Enable the eMMC cache feature on <device>.
+NOTE! The cache is an optional feature on devices >= eMMC4.5.
+.TP
+.BR "cache disable <device>"
+Disable the eMMC cache feature on <device>.
+NOTE! The cache is an optional feature on devices >= eMMC4.5.
+.TP
+.BR "<cmd> --help"
+Show detailed help for a command or subset of commands.
+
+.SH
+EXAMPLES
+.TP
+Program authentication key from stdin:
+echo -n AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH | mmc rpmb write-key /dev/mmcblk0rpmb -
+.TP
+Write a block of 256 bytes of data to an rpmb device:
+$ (awk 'BEGIN {while (c++<256) printf "a"}' | echo -n AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH) | mmc rpmb write-block /dev/mmcblk0rpmb 0x02 - -
+.TP
+Read a block of 256 bytes of data from an rpmb device to stdout:
+  $ echo -n AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH | mmc rpmb read-block /dev/mmcblk0rpmb 0x02 2 /tmp/block -
+.TP
+Read 2 blocks of 256 bytes from rpmb device to /tmp/block without verification:
+$ mmc rpmb read-block /dev/mmcblk0rpmb 0x02 2 /tmp/block

File diff suppressed because it is too large
+ 73 - 0
emmc_hal_lib/mmc-utils/mmc.c


+ 199 - 0
emmc_hal_lib/mmc-utils/mmc.h

@@ -0,0 +1,199 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Modified to add field firmware update support,
+ * those modifications are Copyright (c) 2016 SanDisk Corp.
+ */
+
+#include <linux/mmc/ioctl.h>
+
+/* From kernel linux/major.h */
+#define MMC_BLOCK_MAJOR			179
+
+/* From kernel linux/mmc/mmc.h */
+#define MMC_SWITCH		6	/* ac	[31:0] See below	R1b */
+#define MMC_SEND_EXT_CSD	8	/* adtc				R1  */
+#define MMC_SEND_STATUS		13	/* ac   [31:16] RCA        R1  */
+#define R1_SWITCH_ERROR   (1 << 7)  /* sx, c */
+#define MMC_SWITCH_MODE_WRITE_BYTE	0x03	/* Set target to value */
+#define MMC_READ_MULTIPLE_BLOCK  18   /* adtc [31:0] data addr   R1  */
+#define MMC_WRITE_BLOCK		24	/* adtc [31:0] data addr	R1  */
+#define MMC_WRITE_MULTIPLE_BLOCK 25   /* adtc                    R1  */
+#define MMC_SET_WRITE_PROT	28    /* ac   [31:0] data addr   R1b */
+#define MMC_CLEAR_WRITE_PROT	29    /* ac   [31:0] data addr   R1b */
+#define MMC_SEND_WRITE_PROT_TYPE 31   /* ac   [31:0] data addr   R1  */
+
+/*
+ * EXT_CSD fields
+ */
+#define EXT_CSD_S_CMD_SET		504
+#define EXT_CSD_HPI_FEATURE		503
+#define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
+#define EXT_CSD_SUPPORTED_MODES		493	/* RO */
+#define EXT_CSD_FFU_FEATURES		492	/* RO */
+#define EXT_CSD_FFU_ARG_3		490	/* RO */
+#define EXT_CSD_FFU_ARG_2		489	/* RO */
+#define EXT_CSD_FFU_ARG_1		488	/* RO */
+#define EXT_CSD_FFU_ARG_0		487	/* RO */
+#define EXT_CSD_CMDQ_DEPTH		307	/* RO */
+#define EXT_CSD_CMDQ_SUPPORT		308	/* RO */
+#define EXT_CSD_NUM_OF_FW_SEC_PROG_3	305	/* RO */
+#define EXT_CSD_NUM_OF_FW_SEC_PROG_2	304	/* RO */
+#define EXT_CSD_NUM_OF_FW_SEC_PROG_1	303	/* RO */
+#define EXT_CSD_NUM_OF_FW_SEC_PROG_0	302	/* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 	269	/* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 	268	/* RO */
+#define EXT_CSD_PRE_EOL_INFO		267	/* RO */
+#define EXT_CSD_FIRMWARE_VERSION	254	/* RO */
+#define EXT_CSD_CACHE_SIZE_3		252
+#define EXT_CSD_CACHE_SIZE_2		251
+#define EXT_CSD_CACHE_SIZE_1		250
+#define EXT_CSD_CACHE_SIZE_0		249
+#define EXT_CSD_BOOT_INFO		228	/* R/W */
+#define EXT_CSD_HC_ERASE_GRP_SIZE	224
+#define EXT_CSD_HC_WP_GRP_SIZE		221
+#define EXT_CSD_SEC_COUNT_3		215
+#define EXT_CSD_SEC_COUNT_2		214
+#define EXT_CSD_SEC_COUNT_1		213
+#define EXT_CSD_SEC_COUNT_0		212
+#define EXT_CSD_PART_SWITCH_TIME	199
+#define EXT_CSD_REV			192
+#define EXT_CSD_BOOT_CFG		179
+#define EXT_CSD_PART_CONFIG		179
+#define EXT_CSD_BOOT_BUS_CONDITIONS	177
+#define EXT_CSD_ERASE_GROUP_DEF		175
+#define EXT_CSD_BOOT_WP			173
+#define EXT_CSD_USER_WP			171
+#define EXT_CSD_FW_CONFIG		169	/* R/W */
+#define EXT_CSD_WR_REL_SET		167
+#define EXT_CSD_WR_REL_PARAM		166
+#define EXT_CSD_SANITIZE_START		165
+#define EXT_CSD_BKOPS_EN		163	/* R/W */
+#define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_MAX_ENH_SIZE_MULT_2	159
+#define EXT_CSD_MAX_ENH_SIZE_MULT_1	158
+#define EXT_CSD_MAX_ENH_SIZE_MULT_0	157
+#define EXT_CSD_PARTITIONS_ATTRIBUTE	156	/* R/W */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
+#define EXT_CSD_GP_SIZE_MULT_4_2	154
+#define EXT_CSD_GP_SIZE_MULT_4_1	153
+#define EXT_CSD_GP_SIZE_MULT_4_0	152
+#define EXT_CSD_GP_SIZE_MULT_3_2	151
+#define EXT_CSD_GP_SIZE_MULT_3_1	150
+#define EXT_CSD_GP_SIZE_MULT_3_0	149
+#define EXT_CSD_GP_SIZE_MULT_2_2	148
+#define EXT_CSD_GP_SIZE_MULT_2_1	147
+#define EXT_CSD_GP_SIZE_MULT_2_0	146
+#define EXT_CSD_GP_SIZE_MULT_1_2	145
+#define EXT_CSD_GP_SIZE_MULT_1_1	144
+#define EXT_CSD_GP_SIZE_MULT_1_0	143
+#define EXT_CSD_ENH_SIZE_MULT_2		142
+#define EXT_CSD_ENH_SIZE_MULT_1		141
+#define EXT_CSD_ENH_SIZE_MULT_0		140
+#define EXT_CSD_ENH_START_ADDR_3	139
+#define EXT_CSD_ENH_START_ADDR_2	138
+#define EXT_CSD_ENH_START_ADDR_1	137
+#define EXT_CSD_ENH_START_ADDR_0	136
+#define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
+#define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
+#define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
+#define EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_1	53
+#define EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_0	52
+#define EXT_CSD_CACHE_CTRL		33
+#define EXT_CSD_MODE_CONFIG		30
+#define EXT_CSD_MODE_OPERATION_CODES	29	/* W */
+#define EXT_CSD_FFU_STATUS		26	/* R */
+#define EXT_CSD_SECURE_REMOVAL_TYPE	16	/* R/W */
+#define EXT_CSD_CMDQ_MODE_EN		15	/* R/W */
+
+/*
+ * WR_REL_PARAM field definitions
+ */
+#define HS_CTRL_REL	(1<<0)
+#define EN_REL_WR	(1<<2)
+
+/*
+ * BKOPS_EN field definition
+ */
+#define BKOPS_ENABLE	(1<<0)
+
+/*
+ * EXT_CSD field definitions
+ */
+#define EXT_CSD_CONFIG_SECRM_TYPE	(0x30)
+#define EXT_CSD_SUPPORTED_SECRM_TYPE	(0x0f)
+#define EXT_CSD_FFU_INSTALL		(0x01)
+#define EXT_CSD_FFU_MODE		(0x01)
+#define EXT_CSD_NORMAL_MODE		(0x00)
+#define EXT_CSD_FFU			(1<<0)
+#define EXT_CSD_UPDATE_DISABLE		(1<<0)
+#define EXT_CSD_HPI_SUPP		(1<<0)
+#define EXT_CSD_HPI_IMPL		(1<<1)
+#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS	(0x40)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS	(0x10)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_EN	(0x04)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_EN	(0x01)
+#define EXT_CSD_BOOT_INFO_HS_MODE	(1<<2)
+#define EXT_CSD_BOOT_INFO_DDR_DDR	(1<<1)
+#define EXT_CSD_BOOT_INFO_ALT		(1<<0)
+#define EXT_CSD_BOOT_CFG_ACK		(1<<6)
+#define EXT_CSD_BOOT_CFG_EN		(0x38)
+#define EXT_CSD_BOOT_CFG_ACC		(0x07)
+#define EXT_CSD_RST_N_EN_MASK		(0x03)
+#define EXT_CSD_HW_RESET_EN		(0x01)
+#define EXT_CSD_HW_RESET_DIS		(0x02)
+#define EXT_CSD_PART_CONFIG_ACC_MASK	  (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_NONE	  (0x0)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0	  (0x1)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT1	  (0x2)
+#define EXT_CSD_PART_CONFIG_ACC_USER_AREA (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_ACK	  (0x40)
+#define EXT_CSD_PARTITIONING_EN		(1<<0)
+#define EXT_CSD_ENH_ATTRIBUTE_EN	(1<<1)
+#define EXT_CSD_ENH_4			(1<<4)
+#define EXT_CSD_ENH_3			(1<<3)
+#define EXT_CSD_ENH_2			(1<<2)
+#define EXT_CSD_ENH_1			(1<<1)
+#define EXT_CSD_ENH_USR			(1<<0)
+#define EXT_CSD_REV_V5_1		8
+#define EXT_CSD_REV_V5_0		7
+#define EXT_CSD_REV_V4_5		6
+#define EXT_CSD_REV_V4_4_1		5
+#define EXT_CSD_REV_V4_3		3
+#define EXT_CSD_REV_V4_2		2
+#define EXT_CSD_REV_V4_1		1
+#define EXT_CSD_REV_V4_0		0
+
+
+/* From kernel linux/mmc/core.h */
+#define MMC_RSP_PRESENT	(1 << 0)
+#define MMC_RSP_136	(1 << 1)		/* 136 bit response */
+#define MMC_RSP_CRC	(1 << 2)		/* expect valid crc */
+#define MMC_RSP_BUSY	(1 << 3)		/* card may send busy */
+#define MMC_RSP_OPCODE	(1 << 4)		/* response contains opcode */
+
+#define MMC_CMD_AC	(0 << 5)
+#define MMC_CMD_ADTC	(1 << 5)
+
+#define MMC_RSP_SPI_S1	(1 << 7)		/* one status byte */
+#define MMC_RSP_SPI_BUSY (1 << 10)		/* card may send busy */
+
+#define MMC_RSP_SPI_R1	(MMC_RSP_SPI_S1)
+#define MMC_RSP_SPI_R1B	(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
+
+#define MMC_RSP_R1	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1B	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)

+ 2659 - 0
emmc_hal_lib/mmc-utils/mmc_cmds.c

@@ -0,0 +1,2659 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Modified to add field firmware update support,
+ * those modifications are Copyright (c) 2016 SanDisk Corp.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdint.h>
+#include <assert.h>
+#include <linux/fs.h> /* for BLKGETSIZE */
+
+#include "mmc.h"
+#include "mmc_cmds.h"
+#include "3rdparty/hmac_sha/hmac_sha2.h"
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define WP_BLKS_PER_QUERY 32
+
+#define USER_WP_PERM_PSWD_DIS	0x80
+#define USER_WP_CD_PERM_WP_DIS	0x40
+#define USER_WP_US_PERM_WP_DIS	0x10
+#define USER_WP_US_PWR_WP_DIS	0x08
+#define USER_WP_US_PERM_WP_EN	0x04
+#define USER_WP_US_PWR_WP_EN	0x01
+#define USER_WP_CLEAR (USER_WP_US_PERM_WP_DIS | USER_WP_US_PWR_WP_DIS	\
+			| USER_WP_US_PERM_WP_EN | USER_WP_US_PWR_WP_EN)
+
+#define WPTYPE_NONE 0
+#define WPTYPE_TEMP 1
+#define WPTYPE_PWRON 2
+#define WPTYPE_PERM 3
+
+
+int read_extcsd(int fd, __u8 *ext_csd)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+	memset(&idata, 0, sizeof(idata));
+	memset(ext_csd, 0, sizeof(__u8) * 512);
+	idata.write_flag = 0;
+	idata.opcode = MMC_SEND_EXT_CSD;
+	idata.arg = 0;
+	idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+	idata.blksz = 512;
+	idata.blocks = 1;
+	mmc_ioc_cmd_set_data(idata, ext_csd);
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+		perror("ioctl");
+
+	return ret;
+}
+
+int write_extcsd_value(int fd, __u8 index, __u8 value)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+
+	memset(&idata, 0, sizeof(idata));
+	idata.write_flag = 1;
+	idata.opcode = MMC_SWITCH;
+	idata.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+			(index << 16) |
+			(value << 8) |
+			EXT_CSD_CMD_SET_NORMAL;
+	idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+		perror("ioctl");
+
+	return ret;
+}
+
+int send_status(int fd, __u32 *response)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+
+	memset(&idata, 0, sizeof(idata));
+	idata.opcode = MMC_SEND_STATUS;
+	idata.arg = (1 << 16);
+	idata.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+	perror("ioctl");
+
+	*response = idata.response[0];
+
+	return ret;
+}
+
+static __u32 get_size_in_blks(int fd)
+{
+	int res;
+	int size;
+
+	res = ioctl(fd, BLKGETSIZE, &size);
+	if (res) {
+		fprintf(stderr, "Error getting device size, errno: %d\n",
+			errno);
+		perror("");
+		return -1;
+	}
+	return size;
+}
+
+static int set_write_protect(int fd, __u32 blk_addr, int on_off)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+
+	memset(&idata, 0, sizeof(idata));
+	idata.write_flag = 1;
+	if (on_off)
+		idata.opcode = MMC_SET_WRITE_PROT;
+	else
+		idata.opcode = MMC_CLEAR_WRITE_PROT;
+	idata.arg = blk_addr;
+	idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+		perror("ioctl");
+
+	return ret;
+}
+
+static int send_write_protect_type(int fd, __u32 blk_addr, __u64 *group_bits)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+	__u8 buf[8];
+	__u64 bits = 0;
+	int x;
+
+	memset(&idata, 0, sizeof(idata));
+	idata.write_flag = 0;
+	idata.opcode = MMC_SEND_WRITE_PROT_TYPE;
+	idata.blksz      = 8,
+	idata.blocks     = 1,
+	idata.arg = blk_addr;
+	idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+	mmc_ioc_cmd_set_data(idata, buf);
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+		perror("ioctl");
+	for (x = 0; x < sizeof(buf); x++)
+		bits |= (__u64)(buf[7 - x]) << (x * 8);
+	*group_bits = bits;
+	return ret;
+}
+
+static void print_writeprotect_boot_status(__u8 *ext_csd)
+{
+	__u8 reg;
+	__u8 ext_csd_rev = ext_csd[EXT_CSD_REV];
+
+	/* A43: reserved [174:0] */
+	if (ext_csd_rev >= 5) {
+		printf("Boot write protection status registers"
+			" [BOOT_WP_STATUS]: 0x%02x\n", ext_csd[174]);
+
+		reg = ext_csd[EXT_CSD_BOOT_WP];
+		printf("Boot Area Write protection [BOOT_WP]: 0x%02x\n", reg);
+		printf(" Power ro locking: ");
+		if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
+			printf("not possible\n");
+		else
+			printf("possible\n");
+
+		printf(" Permanent ro locking: ");
+		if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_DIS)
+			printf("not possible\n");
+		else
+			printf("possible\n");
+
+		printf(" ro lock status: ");
+		if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
+			printf("locked until next power on\n");
+		else if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
+			printf("locked permanently\n");
+		else
+			printf("not locked\n");
+	}
+}
+
+static int get_wp_group_size_in_blks(__u8 *ext_csd, __u32 *size)
+{
+	__u8 ext_csd_rev = ext_csd[EXT_CSD_REV];
+
+	if ((ext_csd_rev < 5) || (ext_csd[EXT_CSD_ERASE_GROUP_DEF] == 0))
+		return 1;
+
+	*size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
+		ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * 1024;
+	return 0;
+}
+
+
+int do_writeprotect_boot_get(int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc writeprotect boot get </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	print_writeprotect_boot_status(ext_csd);
+
+	return ret;
+}
+
+int do_writeprotect_boot_set(int nargs, char **argv)
+{
+	__u8 ext_csd[512], value;
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc writeprotect boot set </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	value = ext_csd[EXT_CSD_BOOT_WP] |
+		EXT_CSD_BOOT_WP_B_PWR_WP_EN;
+	ret = write_extcsd_value(fd, EXT_CSD_BOOT_WP, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_BOOT_WP, device);
+		exit(1);
+	}
+
+	return ret;
+}
+
+static char *prot_desc[] = {
+	"No",
+	"Temporary",
+	"Power-on",
+	"Permanent"
+};
+
+static void print_wp_status(__u32 wp_sizeblks, __u32 start_group,
+			__u32 end_group, int rptype)
+{
+	printf("Write Protect Groups %d-%d (Blocks %d-%d), ",
+		start_group, end_group,
+		start_group * wp_sizeblks, ((end_group + 1) * wp_sizeblks) - 1);
+	printf("%s Write Protection\n", prot_desc[rptype]);
+}
+
+
+int do_writeprotect_user_get(int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+	int x;
+	int y = 0;
+	__u32 wp_sizeblks;
+	__u32 dev_sizeblks;
+	__u32 cnt;
+	__u64 bits;
+	__u32 wpblk;
+	__u32 last_wpblk = 0;
+	__u32 prot;
+	__u32 last_prot = -1;
+	int remain;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc writeprotect user get </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	ret = get_wp_group_size_in_blks(ext_csd, &wp_sizeblks);
+	if (ret)
+		exit(1);
+	printf("Write Protect Group size in blocks/bytes: %d/%d\n",
+		wp_sizeblks, wp_sizeblks * 512);
+	dev_sizeblks = get_size_in_blks(fd);
+	cnt = dev_sizeblks / wp_sizeblks;
+	for (x = 0; x < cnt; x += WP_BLKS_PER_QUERY) {
+		ret = send_write_protect_type(fd, x * wp_sizeblks, &bits);
+		if (ret)
+			break;
+		remain = cnt - x;
+		if (remain > WP_BLKS_PER_QUERY)
+			remain = WP_BLKS_PER_QUERY;
+		for (y = 0; y < remain; y++) {
+			prot = (bits >> (y * 2)) & 0x3;
+			if (prot != last_prot) {
+				/* not first time */
+				if (last_prot != -1) {
+					wpblk = x + y;
+					print_wp_status(wp_sizeblks,
+							last_wpblk,
+							wpblk - 1,
+							last_prot);
+					last_wpblk = wpblk;
+				}
+				last_prot = prot;
+			}
+		}
+	}
+	if (last_wpblk != (x + y - 1))
+		print_wp_status(wp_sizeblks, last_wpblk, cnt - 1, last_prot);
+
+	return ret;
+}
+
+int do_writeprotect_user_set(int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+	int blk_start;
+	int blk_cnt;
+	__u32 wp_blks;
+	__u8 user_wp;
+	int x;
+	int wptype;
+
+	if (nargs != 5)
+		goto usage;
+	device = argv[4];
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+	if (!strcmp(argv[1], "none")) {
+		wptype = WPTYPE_NONE;
+	} else if (!strcmp(argv[1], "temp")) {
+		wptype = WPTYPE_TEMP;
+	} else if (!strcmp(argv[1], "pwron")) {
+		wptype = WPTYPE_PWRON;
+#ifdef DANGEROUS_COMMANDS_ENABLED
+	} else if (!strcmp(argv[1], "perm")) {
+		wptype = WPTYPE_PERM;
+#endif /* DANGEROUS_COMMANDS_ENABLED */
+	} else {
+		fprintf(stderr, "Error, invalid \"type\"\n");
+		goto usage;
+	}
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+	ret = get_wp_group_size_in_blks(ext_csd, &wp_blks);
+	if (ret) {
+		fprintf(stderr, "Operation not supported for this device\n");
+		exit(1);
+	}
+	blk_start = strtol(argv[2], NULL, 0);
+	blk_cnt = strtol(argv[3], NULL, 0);
+	if ((blk_start % wp_blks) || (blk_cnt % wp_blks)) {
+		fprintf(stderr, "<start block> and <blocks> must be a ");
+		fprintf(stderr, "multiple of the Write Protect Group (%d)\n",
+			wp_blks);
+		exit(1);
+	}
+	if (wptype != WPTYPE_NONE) {
+		user_wp = ext_csd[EXT_CSD_USER_WP];
+		user_wp &= ~USER_WP_CLEAR;
+		switch (wptype) {
+		case WPTYPE_TEMP:
+			break;
+		case WPTYPE_PWRON:
+			user_wp |= USER_WP_US_PWR_WP_EN;
+			break;
+		case WPTYPE_PERM:
+			user_wp |= USER_WP_US_PERM_WP_EN;
+			break;
+		}
+		if (user_wp != ext_csd[EXT_CSD_USER_WP]) {
+			ret = write_extcsd_value(fd, EXT_CSD_USER_WP, user_wp);
+			if (ret) {
+				fprintf(stderr, "Error setting EXT_CSD\n");
+				exit(1);
+			}
+		}
+	}
+	for (x = 0; x < blk_cnt; x += wp_blks) {
+		ret = set_write_protect(fd, blk_start + x,
+					wptype != WPTYPE_NONE);
+		if (ret) {
+			fprintf(stderr,
+				"Could not set write protect for %s\n", device);
+			exit(1);
+		}
+	}
+	if (wptype != WPTYPE_NONE) {
+		ret = write_extcsd_value(fd, EXT_CSD_USER_WP,
+					ext_csd[EXT_CSD_USER_WP]);
+		if (ret) {
+			fprintf(stderr, "Error restoring EXT_CSD\n");
+			exit(1);
+		}
+	}
+	return ret;
+
+usage:
+	fprintf(stderr,
+		"Usage: mmc writeprotect user set <type><start block><blocks><device>\n");
+	exit(1);
+}
+
+int do_disable_512B_emulation(int nargs, char **argv)
+{
+	__u8 ext_csd[512], native_sector_size, data_sector_size, wr_rel_param;
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc disable 512B emulation </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	wr_rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+	native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
+	data_sector_size = ext_csd[EXT_CSD_DATA_SECTOR_SIZE];
+
+	if (native_sector_size && !data_sector_size &&
+	   (wr_rel_param & EN_REL_WR)) {
+		ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1);
+
+		if (ret) {
+			fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+					1, EXT_CSD_NATIVE_SECTOR_SIZE, device);
+			exit(1);
+		}
+		printf("MMC disable 512B emulation successful.  Now reset the device to switch to 4KB native sector mode.\n");
+	} else if (native_sector_size && data_sector_size) {
+		printf("MMC 512B emulation mode is already disabled; doing nothing.\n");
+	} else {
+		printf("MMC does not support disabling 512B emulation mode.\n");
+	}
+
+	return ret;
+}
+
+int do_write_boot_en(int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	__u8 value = 0;
+	int fd, ret;
+	char *device;
+	int boot_area, send_ack;
+
+	if (nargs != 4) {
+		fprintf(stderr, "Usage: mmc bootpart enable <partition_number> <send_ack> </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	/*
+	 * If <send_ack> is 1, the device will send acknowledgment
+	 * pattern "010" to the host when boot operation begins.
+	 * If <send_ack> is 0, it won't.
+	 */
+	boot_area = strtol(argv[1], NULL, 10);
+	send_ack = strtol(argv[2], NULL, 10);
+	device = argv[3];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	value = ext_csd[EXT_CSD_PART_CONFIG];
+
+	switch (boot_area) {
+	case EXT_CSD_PART_CONFIG_ACC_NONE:
+		value &= ~(7 << 3);
+		break;
+	case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+		value |= (1 << 3);
+		value &= ~(3 << 4);
+		break;
+	case EXT_CSD_PART_CONFIG_ACC_BOOT1:
+		value |= (1 << 4);
+		value &= ~(1 << 3);
+		value &= ~(1 << 5);
+		break;
+	case EXT_CSD_PART_CONFIG_ACC_USER_AREA:
+		value |= (boot_area << 3);
+		break;
+	default:
+		fprintf(stderr, "Cannot enable the boot area\n");
+		exit(1);
+	}
+	if (send_ack)
+		value |= EXT_CSD_PART_CONFIG_ACC_ACK;
+	else
+		value &= ~EXT_CSD_PART_CONFIG_ACC_ACK;
+
+	ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_PART_CONFIG, device);
+		exit(1);
+	}
+	return ret;
+}
+
+int do_boot_bus_conditions_set(int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	__u8 value = 0;
+	int fd, ret;
+	char *device;
+
+	if (nargs != 5) {
+		fprintf(stderr, "Usage: mmc: bootbus set <boot_mode> <reset_boot_bus_conditions> <boot_bus_width> <device>\n");
+		exit(1);
+	}
+
+	if (strcmp(argv[1], "single_backward") == 0)
+		value |= 0;
+	else if (strcmp(argv[1], "single_hs") == 0)
+		value |= 0x8;
+	else if (strcmp(argv[1], "dual") == 0)
+		value |= 0x10;
+	else {
+		fprintf(stderr, "illegal <boot_mode> specified\n");
+		exit(1);
+	}
+
+	if (strcmp(argv[2], "x1") == 0)
+		value |= 0;
+	else if (strcmp(argv[2], "retain") == 0)
+		value |= 0x4;
+	else {
+		fprintf(stderr,
+			"illegal <reset_boot_bus_conditions> specified\n");
+		exit(1);
+	}
+
+	if (strcmp(argv[3], "x1") == 0)
+		value |= 0;
+	else if (strcmp(argv[3], "x4") == 0)
+		value |= 0x1;
+	else if (strcmp(argv[3], "x8") == 0)
+		value |= 0x2;
+	else {
+		fprintf(stderr,	"illegal <boot_bus_width> specified\n");
+		exit(1);
+	}
+
+	device = argv[4];
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+	printf("Changing ext_csd[BOOT_BUS_CONDITIONS] from 0x%02x to 0x%02x\n",
+		ext_csd[EXT_CSD_BOOT_BUS_CONDITIONS], value);
+
+	ret = write_extcsd_value(fd, EXT_CSD_BOOT_BUS_CONDITIONS, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_BOOT_BUS_CONDITIONS, device);
+		exit(1);
+	}
+	close(fd);
+	return ret;
+}
+
+int do_hwreset(int value, int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc hwreset enable </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	if ((ext_csd[EXT_CSD_RST_N_FUNCTION] & EXT_CSD_RST_N_EN_MASK) ==
+	    EXT_CSD_HW_RESET_EN) {
+		fprintf(stderr,
+			"H/W Reset is already permanently enabled on %s\n",
+			device);
+		exit(1);
+	}
+	if ((ext_csd[EXT_CSD_RST_N_FUNCTION] & EXT_CSD_RST_N_EN_MASK) ==
+	    EXT_CSD_HW_RESET_DIS) {
+		fprintf(stderr,
+			"H/W Reset is already permanently disabled on %s\n",
+			device);
+		exit(1);
+	}
+
+	ret = write_extcsd_value(fd, EXT_CSD_RST_N_FUNCTION, value);
+	if (ret) {
+		fprintf(stderr,
+			"Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_RST_N_FUNCTION, device);
+		exit(1);
+	}
+
+	return ret;
+}
+
+int do_hwreset_en(int nargs, char **argv)
+{
+	return do_hwreset(EXT_CSD_HW_RESET_EN, nargs, argv);
+}
+
+int do_hwreset_dis(int nargs, char **argv)
+{
+	return do_hwreset(EXT_CSD_HW_RESET_DIS, nargs, argv);
+}
+
+int do_write_bkops_en(int nargs, char **argv)
+{
+	__u8 ext_csd[512], value = 0;
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+	       fprintf(stderr, "Usage: mmc bkops enable </path/to/mmcblkX>\n");
+	       exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
+		fprintf(stderr, "%s doesn't support BKOPS\n", device);
+		exit(1);
+	}
+
+	ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_BKOPS_EN, device);
+		exit(1);
+	}
+
+	return ret;
+}
+
+int do_status_get(int nargs, char **argv)
+{
+	__u32 response;
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc status get </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = send_status(fd, &response);
+	if (ret) {
+		fprintf(stderr, "Could not read response to SEND_STATUS from %s\n", device);
+		exit(1);
+	}
+
+	printf("SEND_STATUS response: 0x%08x\n", response);
+
+	return ret;
+}
+
+unsigned int get_sector_count(__u8 *ext_csd)
+{
+	return (ext_csd[EXT_CSD_SEC_COUNT_3] << 24) |
+	(ext_csd[EXT_CSD_SEC_COUNT_2] << 16) |
+	(ext_csd[EXT_CSD_SEC_COUNT_1] << 8)  |
+	ext_csd[EXT_CSD_SEC_COUNT_0];
+}
+
+int is_blockaddresed(__u8 *ext_csd)
+{
+	unsigned int sectors = get_sector_count(ext_csd);
+
+	/* over 2GiB devices are block-addressed */
+	return (sectors > (2u * 1024 * 1024 * 1024) / 512);
+}
+
+unsigned int get_hc_wp_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[221];
+}
+
+unsigned int get_hc_erase_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[224];
+}
+
+int set_partitioning_setting_completed(int dry_run, const char * const device,
+		int fd)
+{
+	int ret;
+
+	if (dry_run == 1) {
+		fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n");
+		fprintf(stderr, "These changes will not take effect neither "
+			"now nor after a power cycle\n");
+		return 1;
+	} else if (dry_run == 2) {
+		printf("-c given, expecting more partition settings before "
+			"writing PARTITION_SETTING_COMPLETED\n");
+		return 0;
+	}
+
+	fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n");
+	ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x1 to "
+			"EXT_CSD[%d] in %s\n",
+			EXT_CSD_PARTITION_SETTING_COMPLETED, device);
+		return 1;
+	}
+
+	__u32 response;
+	ret = send_status(fd, &response);
+	if (ret) {
+		fprintf(stderr, "Could not get response to SEND_STATUS "
+			"from %s\n", device);
+		return 1;
+	}
+
+	if (response & R1_SWITCH_ERROR) {
+		fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED "
+			"failed on %s\n", device);
+		return 1;
+	}
+
+	fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED on "
+		"%s SUCCESS\n", device);
+	fprintf(stderr, "Device power cycle needed for settings to "
+		"take effect.\n"
+		"Confirm that PARTITION_SETTING_COMPLETED bit is set "
+		"using 'extcsd read' after power cycle\n");
+
+	return 0;
+}
+
+int check_enhanced_area_total_limit(const char * const device, int fd)
+{
+	__u8 ext_csd[512];
+	__u32 regl;
+	unsigned long max_enh_area_sz, user_area_sz, enh_area_sz = 0;
+	unsigned long gp4_part_sz, gp3_part_sz, gp2_part_sz, gp1_part_sz;
+	unsigned long total_sz, total_gp_user_sz;
+	unsigned int wp_sz, erase_sz;
+	int ret;
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+	wp_sz = get_hc_wp_grp_size(ext_csd);
+	erase_sz = get_hc_erase_grp_size(ext_csd);
+
+	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_4_2] << 16) |
+		(ext_csd[EXT_CSD_GP_SIZE_MULT_4_1] << 8) |
+		ext_csd[EXT_CSD_GP_SIZE_MULT_4_0];
+	gp4_part_sz = 512l * regl * erase_sz * wp_sz;
+	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_4) {
+		enh_area_sz += gp4_part_sz;
+		printf("Enhanced GP4 Partition Size [GP_SIZE_MULT_4]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", gp4_part_sz);
+	}
+
+	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_3_2] << 16) |
+		(ext_csd[EXT_CSD_GP_SIZE_MULT_3_1] << 8) |
+		ext_csd[EXT_CSD_GP_SIZE_MULT_3_0];
+	gp3_part_sz = 512l * regl * erase_sz * wp_sz;
+	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_3) {
+		enh_area_sz += gp3_part_sz;
+		printf("Enhanced GP3 Partition Size [GP_SIZE_MULT_3]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", gp3_part_sz);
+	}
+
+	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_2_2] << 16) |
+		(ext_csd[EXT_CSD_GP_SIZE_MULT_2_1] << 8) |
+		ext_csd[EXT_CSD_GP_SIZE_MULT_2_0];
+	gp2_part_sz = 512l * regl * erase_sz * wp_sz;
+	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_2) {
+		enh_area_sz += gp2_part_sz;
+		printf("Enhanced GP2 Partition Size [GP_SIZE_MULT_2]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", gp2_part_sz);
+	}
+
+	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_1_2] << 16) |
+		(ext_csd[EXT_CSD_GP_SIZE_MULT_1_1] << 8) |
+		ext_csd[EXT_CSD_GP_SIZE_MULT_1_0];
+	gp1_part_sz = 512l * regl * erase_sz * wp_sz;
+	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_1) {
+		enh_area_sz += gp1_part_sz;
+		printf("Enhanced GP1 Partition Size [GP_SIZE_MULT_1]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", gp1_part_sz);
+	}
+
+	regl = (ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) |
+		(ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) |
+		ext_csd[EXT_CSD_ENH_SIZE_MULT_0];
+	user_area_sz = 512l * regl * erase_sz * wp_sz;
+	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_USR) {
+		enh_area_sz += user_area_sz;
+		printf("Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", user_area_sz);
+	}
+
+	regl = (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_2] << 16) |
+		(ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_1] << 8) |
+		ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_0];
+	max_enh_area_sz = 512l * regl * erase_sz * wp_sz;
+	printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n", regl);
+	printf(" i.e. %lu KiB\n", max_enh_area_sz);
+	if (enh_area_sz > max_enh_area_sz) {
+		fprintf(stderr,
+			"Programmed total enhanced size %lu KiB cannot exceed max enhanced area %lu KiB %s\n",
+			enh_area_sz, max_enh_area_sz, device);
+		return 1;
+	}
+	total_sz = get_sector_count(ext_csd) / 2;
+	total_gp_user_sz = gp4_part_sz + gp3_part_sz + gp2_part_sz +
+				gp1_part_sz + user_area_sz;
+	if (total_gp_user_sz > total_sz) {
+		fprintf(stderr,
+			"requested total partition size %lu KiB cannot exceed card capacity %lu KiB %s\n",
+			total_gp_user_sz, total_sz, device);
+		return 1;
+	}
+
+	return 0;
+}
+
+int do_create_gp_partition(int nargs, char **argv)
+{
+	__u8 value;
+	__u8 ext_csd[512];
+	__u8 address;
+	int fd, ret;
+	char *device;
+	int dry_run = 1;
+	int partition, enh_attr, ext_attr;
+	unsigned int length_kib, gp_size_mult;
+	unsigned long align;
+
+	if (nargs != 7) {
+		fprintf(stderr, "Usage: mmc gp create <-y|-n|-c> <length KiB> <partition> <enh_attr> <ext_attr> </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	if (!strcmp("-y", argv[1])) {
+		dry_run = 0;
+        } else if (!strcmp("-c", argv[1])) {
+		dry_run = 2;
+	}
+
+	length_kib = strtol(argv[2], NULL, 10);
+	partition = strtol(argv[3], NULL, 10);
+	enh_attr = strtol(argv[4], NULL, 10);
+	ext_attr = strtol(argv[5], NULL, 10);
+	device = argv[6];
+
+	if (partition < 1 || partition > 4) {
+		printf("Invalid gp partition number; valid range [1-4].\n");
+		exit(1);
+	}
+
+	if (enh_attr && ext_attr) {
+		printf("Not allowed to set both enhanced attribute and extended attribute\n");
+		exit(1);
+	}
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	/* assert not PARTITION_SETTING_COMPLETED */
+	if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED]) {
+		printf(" Device is already partitioned\n");
+		exit(1);
+	}
+
+	align = 512l * get_hc_wp_grp_size(ext_csd) * get_hc_erase_grp_size(ext_csd);
+	gp_size_mult = (length_kib + align/2l) / align;
+
+	/* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
+	ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x1 to EXT_CSD[%d] in %s\n",
+			EXT_CSD_ERASE_GROUP_DEF, device);
+		exit(1);
+	}
+
+	value = (gp_size_mult >> 16) & 0xff;
+	address = EXT_CSD_GP_SIZE_MULT_1_2 + (partition - 1) * 3;
+	ret = write_extcsd_value(fd, address, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, address, device);
+		exit(1);
+	}
+	value = (gp_size_mult >> 8) & 0xff;
+	address = EXT_CSD_GP_SIZE_MULT_1_1 + (partition - 1) * 3;
+	ret = write_extcsd_value(fd, address, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, address, device);
+		exit(1);
+	}
+	value = gp_size_mult & 0xff;
+	address = EXT_CSD_GP_SIZE_MULT_1_0 + (partition - 1) * 3;
+	ret = write_extcsd_value(fd, address, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, address, device);
+		exit(1);
+	}
+
+	value = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
+	if (enh_attr)
+		value |= (1 << partition);
+	else
+		value &= ~(1 << partition);
+
+	ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
+	if (ret) {
+		fprintf(stderr, "Could not write EXT_CSD_ENH_%x to EXT_CSD[%d] in %s\n",
+			partition, EXT_CSD_PARTITIONS_ATTRIBUTE, device);
+		exit(1);
+	}
+
+	address = EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_0 + (partition - 1) / 2;
+	value = ext_csd[address];
+	if (ext_attr)
+		value |= (ext_attr << (4 * ((partition - 1) % 2)));
+	else
+		value &= (0xF << (4 * ((partition % 2))));
+
+	ret = write_extcsd_value(fd, address, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%x to EXT_CSD[%d] in %s\n",
+			value, address, device);
+		exit(1);
+	}
+
+	ret = check_enhanced_area_total_limit(device, fd);
+	if (ret)
+		exit(1);
+
+	if (set_partitioning_setting_completed(dry_run, device, fd))
+		exit(1);
+
+	return 0;
+}
+
+int do_enh_area_set(int nargs, char **argv)
+{
+	__u8 value;
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+	int dry_run = 1;
+	unsigned int start_kib, length_kib, enh_start_addr, enh_size_mult;
+	unsigned long align;
+
+	if (nargs != 5) {
+		fprintf(stderr, "Usage: mmc enh_area set <-y|-n|-c> <start KiB> <length KiB> </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	if (!strcmp("-y", argv[1])) {
+		dry_run = 0;
+	} else if (!strcmp("-c", argv[1])) {
+		dry_run = 2;
+	}
+
+	start_kib = strtol(argv[2], NULL, 10);
+	length_kib = strtol(argv[3], NULL, 10);
+	device = argv[4];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	/* assert ENH_ATTRIBUTE_EN */
+	if (!(ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & EXT_CSD_ENH_ATTRIBUTE_EN))
+	{
+		printf(" Device cannot have enhanced tech.\n");
+		exit(1);
+	}
+
+	/* assert not PARTITION_SETTING_COMPLETED */
+	if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED])
+	{
+		printf(" Device is already partitioned\n");
+		exit(1);
+	}
+
+	align = 512l * get_hc_wp_grp_size(ext_csd) * get_hc_erase_grp_size(ext_csd);
+
+	enh_size_mult = (length_kib + align/2l) / align;
+
+	enh_start_addr = start_kib * (1024 / (is_blockaddresed(ext_csd) ? 512 : 1));
+	enh_start_addr /= align;
+	enh_start_addr *= align;
+
+	/* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
+	ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x1 to "
+			"EXT_CSD[%d] in %s\n",
+			EXT_CSD_ERASE_GROUP_DEF, device);
+		exit(1);
+	}
+
+	/* write to ENH_START_ADDR and ENH_SIZE_MULT and PARTITIONS_ATTRIBUTE's ENH_USR bit */
+	value = (enh_start_addr >> 24) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_3, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_3, device);
+		exit(1);
+	}
+	value = (enh_start_addr >> 16) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_2, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_2, device);
+		exit(1);
+	}
+	value = (enh_start_addr >> 8) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_1, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_1, device);
+		exit(1);
+	}
+	value = enh_start_addr & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_0, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_0, device);
+		exit(1);
+	}
+
+	value = (enh_size_mult >> 16) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_2, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_2, device);
+		exit(1);
+	}
+	value = (enh_size_mult >> 8) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_1, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_1, device);
+		exit(1);
+	}
+	value = enh_size_mult & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_0, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_0, device);
+		exit(1);
+	}
+	value = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] | EXT_CSD_ENH_USR;
+	ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
+	if (ret) {
+		fprintf(stderr, "Could not write EXT_CSD_ENH_USR to "
+			"EXT_CSD[%d] in %s\n",
+			EXT_CSD_PARTITIONS_ATTRIBUTE, device);
+		exit(1);
+	}
+
+	ret = check_enhanced_area_total_limit(device, fd);
+	if (ret)
+		exit(1);
+
+	printf("Done setting ENH_USR area on %s\n", device);
+
+	if (set_partitioning_setting_completed(dry_run, device, fd))
+		exit(1);
+
+	return 0;
+}
+
+int do_write_reliability_set(int nargs, char **argv)
+{
+	__u8 value;
+	__u8 ext_csd[512];
+	int fd, ret;
+
+	int dry_run = 1;
+	int partition;
+	char *device;
+
+	if (nargs != 4) {
+		fprintf(stderr,"Usage: mmc write_reliability set <-y|-n|-c> <partition> </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	if (!strcmp("-y", argv[1])) {
+		dry_run = 0;
+	} else if (!strcmp("-c", argv[1])) {
+		dry_run = 2;
+	}
+
+	partition = strtol(argv[2], NULL, 10);
+	device = argv[3];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	/* assert not PARTITION_SETTING_COMPLETED */
+	if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED])
+	{
+		printf(" Device is already partitioned\n");
+		exit(1);
+	}
+
+	/* assert HS_CTRL_REL */
+	if (!(ext_csd[EXT_CSD_WR_REL_PARAM] & HS_CTRL_REL)) {
+		printf("Cannot set write reliability parameters, WR_REL_SET is "
+				"read-only\n");
+		exit(1);
+	}
+
+	value = ext_csd[EXT_CSD_WR_REL_SET] | (1<<partition);
+	ret = write_extcsd_value(fd, EXT_CSD_WR_REL_SET, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+				value, EXT_CSD_WR_REL_SET, device);
+		exit(1);
+	}
+
+	printf("Done setting EXT_CSD_WR_REL_SET to 0x%02x on %s\n",
+		value, device);
+
+	if (set_partitioning_setting_completed(dry_run, device, fd))
+		exit(1);
+
+	return 0;
+}
+
+int do_read_extcsd(int nargs, char **argv)
+{
+	__u8 ext_csd[512], ext_csd_rev, reg;
+	__u32 regl;
+	int fd, ret;
+	char *device;
+	const char *str;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc extcsd read </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	ext_csd_rev = ext_csd[EXT_CSD_REV];
+
+	switch (ext_csd_rev) {
+	case 8:
+		str = "5.1";
+		break;
+	case 7:
+		str = "5.0";
+		break;
+	case 6:
+		str = "4.5";
+		break;
+	case 5:
+		str = "4.41";
+		break;
+	case 3:
+		str = "4.3";
+		break;
+	case 2:
+		str = "4.2";
+		break;
+	case 1:
+		str = "4.1";
+		break;
+	case 0:
+		str = "4.0";
+		break;
+	default:
+		goto out_free;
+	}
+	printf("=============================================\n");
+	printf("  Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str);
+	printf("=============================================\n\n");
+
+	if (ext_csd_rev < 3)
+		goto out_free; /* No ext_csd */
+
+	/* Parse the Extended CSD registers.
+	 * Reserved bit should be read as "0" in case of spec older
+	 * than A441.
+	 */
+	reg = ext_csd[EXT_CSD_S_CMD_SET];
+	printf("Card Supported Command sets [S_CMD_SET: 0x%02x]\n", reg);
+	if (!reg)
+		printf(" - Standard MMC command sets\n");
+
+	reg = ext_csd[EXT_CSD_HPI_FEATURE];
+	printf("HPI Features [HPI_FEATURE: 0x%02x]: ", reg);
+	if (reg & EXT_CSD_HPI_SUPP) {
+		if (reg & EXT_CSD_HPI_IMPL)
+			printf("implementation based on CMD12\n");
+		else
+			printf("implementation based on CMD13\n");
+	}
+
+	printf("Background operations support [BKOPS_SUPPORT: 0x%02x]\n",
+		ext_csd[502]);
+
+	if (ext_csd_rev >= 6) {
+		printf("Max Packet Read Cmd [MAX_PACKED_READS: 0x%02x]\n",
+			ext_csd[501]);
+		printf("Max Packet Write Cmd [MAX_PACKED_WRITES: 0x%02x]\n",
+			ext_csd[500]);
+		printf("Data TAG support [DATA_TAG_SUPPORT: 0x%02x]\n",
+			ext_csd[499]);
+
+		printf("Data TAG Unit Size [TAG_UNIT_SIZE: 0x%02x]\n",
+			ext_csd[498]);
+		printf("Tag Resources Size [TAG_RES_SIZE: 0x%02x]\n",
+			ext_csd[497]);
+		printf("Context Management Capabilities"
+			" [CONTEXT_CAPABILITIES: 0x%02x]\n", ext_csd[496]);
+		printf("Large Unit Size [LARGE_UNIT_SIZE_M1: 0x%02x]\n",
+			ext_csd[495]);
+		printf("Extended partition attribute support"
+			" [EXT_SUPPORT: 0x%02x]\n", ext_csd[494]);
+		printf("Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x%02x]\n",
+			ext_csd[248]);
+		printf("Power off notification [POWER_OFF_LONG_TIME: 0x%02x]\n",
+			ext_csd[247]);
+		printf("Cache Size [CACHE_SIZE] is %d KiB\n",
+			ext_csd[249] << 0 | (ext_csd[250] << 8) |
+			(ext_csd[251] << 16) | (ext_csd[252] << 24));
+	}
+
+	/* A441: Reserved [501:247]
+	    A43: reserved [246:229] */
+	if (ext_csd_rev >= 5) {
+		printf("Background operations status"
+			" [BKOPS_STATUS: 0x%02x]\n", ext_csd[246]);
+
+		/* CORRECTLY_PRG_SECTORS_NUM [245:242] TODO */
+
+		printf("1st Initialisation Time after programmed sector"
+			" [INI_TIMEOUT_AP: 0x%02x]\n", ext_csd[241]);
+
+		/* A441: reserved [240] */
+		printf("Power class for 52MHz, DDR at 3.6V"
+			" [PWR_CL_DDR_52_360: 0x%02x]\n", ext_csd[239]);
+		printf("Power class for 52MHz, DDR at 1.95V"
+			" [PWR_CL_DDR_52_195: 0x%02x]\n", ext_csd[238]);
+
+		/* A441: reserved [237-236] */
+
+		if (ext_csd_rev >= 6) {
+			printf("Power class for 200MHz at 3.6V"
+				" [PWR_CL_200_360: 0x%02x]\n", ext_csd[237]);
+			printf("Power class for 200MHz, at 1.95V"
+				" [PWR_CL_200_195: 0x%02x]\n", ext_csd[236]);
+		}
+		printf("Minimum Performance for 8bit at 52MHz in DDR mode:\n");
+		printf(" [MIN_PERF_DDR_W_8_52: 0x%02x]\n", ext_csd[235]);
+		printf(" [MIN_PERF_DDR_R_8_52: 0x%02x]\n", ext_csd[234]);
+		/* A441: reserved [233] */
+		printf("TRIM Multiplier [TRIM_MULT: 0x%02x]\n", ext_csd[232]);
+		printf("Secure Feature support [SEC_FEATURE_SUPPORT: 0x%02x]\n",
+			ext_csd[231]);
+	}
+	if (ext_csd_rev == 5) { /* Obsolete in 4.5 */
+		printf("Secure Erase Multiplier [SEC_ERASE_MULT: 0x%02x]\n",
+			ext_csd[230]);
+		printf("Secure TRIM Multiplier [SEC_TRIM_MULT: 0x%02x]\n",
+			ext_csd[229]);
+	}
+	reg = ext_csd[EXT_CSD_BOOT_INFO];
+	printf("Boot Information [BOOT_INFO: 0x%02x]\n", reg);
+	if (reg & EXT_CSD_BOOT_INFO_ALT)
+		printf(" Device supports alternative boot method\n");
+	if (reg & EXT_CSD_BOOT_INFO_DDR_DDR)
+		printf(" Device supports dual data rate during boot\n");
+	if (reg & EXT_CSD_BOOT_INFO_HS_MODE)
+		printf(" Device supports high speed timing during boot\n");
+
+	/* A441/A43: reserved [227] */
+	printf("Boot partition size [BOOT_SIZE_MULTI: 0x%02x]\n", ext_csd[226]);
+	printf("Access size [ACC_SIZE: 0x%02x]\n", ext_csd[225]);
+
+	reg = get_hc_erase_grp_size(ext_csd);
+	printf("High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x%02x]\n",
+		reg);
+	printf(" i.e. %u KiB\n", 512 * reg);
+
+	printf("High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x%02x]\n",
+		ext_csd[223]);
+	printf("Reliable write sector count [REL_WR_SEC_C: 0x%02x]\n",
+		ext_csd[222]);
+
+	reg = get_hc_wp_grp_size(ext_csd);
+	printf("High-capacity W protect group size [HC_WP_GRP_SIZE: 0x%02x]\n",
+		reg);
+	printf(" i.e. %lu KiB\n", 512l * get_hc_erase_grp_size(ext_csd) * reg);
+
+	printf("Sleep current (VCC) [S_C_VCC: 0x%02x]\n", ext_csd[220]);
+	printf("Sleep current (VCCQ) [S_C_VCCQ: 0x%02x]\n", ext_csd[219]);
+	/* A441/A43: reserved [218] */
+	printf("Sleep/awake timeout [S_A_TIMEOUT: 0x%02x]\n", ext_csd[217]);
+	/* A441/A43: reserved [216] */
+
+	unsigned int sectors =	get_sector_count(ext_csd);
+	printf("Sector Count [SEC_COUNT: 0x%08x]\n", sectors);
+	if (is_blockaddresed(ext_csd))
+		printf(" Device is block-addressed\n");
+	else
+		printf(" Device is NOT block-addressed\n");
+
+	/* A441/A43: reserved [211] */
+	printf("Minimum Write Performance for 8bit:\n");
+	printf(" [MIN_PERF_W_8_52: 0x%02x]\n", ext_csd[210]);
+	printf(" [MIN_PERF_R_8_52: 0x%02x]\n", ext_csd[209]);
+	printf(" [MIN_PERF_W_8_26_4_52: 0x%02x]\n", ext_csd[208]);
+	printf(" [MIN_PERF_R_8_26_4_52: 0x%02x]\n", ext_csd[207]);
+	printf("Minimum Write Performance for 4bit:\n");
+	printf(" [MIN_PERF_W_4_26: 0x%02x]\n", ext_csd[206]);
+	printf(" [MIN_PERF_R_4_26: 0x%02x]\n", ext_csd[205]);
+	/* A441/A43: reserved [204] */
+	printf("Power classes registers:\n");
+	printf(" [PWR_CL_26_360: 0x%02x]\n", ext_csd[203]);
+	printf(" [PWR_CL_52_360: 0x%02x]\n", ext_csd[202]);
+	printf(" [PWR_CL_26_195: 0x%02x]\n", ext_csd[201]);
+	printf(" [PWR_CL_52_195: 0x%02x]\n", ext_csd[200]);
+
+	/* A43: reserved [199:198] */
+	if (ext_csd_rev >= 5) {
+		printf("Partition switching timing "
+			"[PARTITION_SWITCH_TIME: 0x%02x]\n", ext_csd[199]);
+		printf("Out-of-interrupt busy timing"
+			" [OUT_OF_INTERRUPT_TIME: 0x%02x]\n", ext_csd[198]);
+	}
+
+	/* A441/A43: reserved	[197] [195] [193] [190] [188]
+	 * [186] [184] [182] [180] [176] */
+
+	if (ext_csd_rev >= 6)
+		printf("I/O Driver Strength [DRIVER_STRENGTH: 0x%02x]\n",
+			ext_csd[197]);
+
+	/* DEVICE_TYPE in A45, CARD_TYPE in A441 */
+	reg = ext_csd[196];
+	printf("Card Type [CARD_TYPE: 0x%02x]\n", reg);
+	if (reg & 0x20) printf(" HS200 Single Data Rate eMMC @200MHz 1.2VI/O\n");
+	if (reg & 0x10) printf(" HS200 Single Data Rate eMMC @200MHz 1.8VI/O\n");
+	if (reg & 0x08) printf(" HS Dual Data Rate eMMC @52MHz 1.2VI/O\n");
+	if (reg & 0x04)	printf(" HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O\n");
+	if (reg & 0x02)	printf(" HS eMMC @52MHz - at rated device voltage(s)\n");
+	if (reg & 0x01) printf(" HS eMMC @26MHz - at rated device voltage(s)\n");
+
+	printf("CSD structure version [CSD_STRUCTURE: 0x%02x]\n", ext_csd[194]);
+	/* ext_csd_rev = ext_csd[EXT_CSD_REV] (already done!!!) */
+	printf("Command set [CMD_SET: 0x%02x]\n", ext_csd[191]);
+	printf("Command set revision [CMD_SET_REV: 0x%02x]\n", ext_csd[189]);
+	printf("Power class [POWER_CLASS: 0x%02x]\n", ext_csd[187]);
+	printf("High-speed interface timing [HS_TIMING: 0x%02x]\n",
+		ext_csd[185]);
+	/* bus_width: ext_csd[183] not readable */
+	printf("Erased memory content [ERASED_MEM_CONT: 0x%02x]\n",
+		ext_csd[181]);
+	reg = ext_csd[EXT_CSD_BOOT_CFG];
+	printf("Boot configuration bytes [PARTITION_CONFIG: 0x%02x]\n", reg);
+	switch ((reg & EXT_CSD_BOOT_CFG_EN)>>3) {
+	case 0x0:
+		printf(" Not boot enable\n");
+		break;
+	case 0x1:
+		printf(" Boot Partition 1 enabled\n");
+		break;
+	case 0x2:
+		printf(" Boot Partition 2 enabled\n");
+		break;
+	case 0x7:
+		printf(" User Area Enabled for boot\n");
+		break;
+	}
+	switch (reg & EXT_CSD_BOOT_CFG_ACC) {
+	case 0x0:
+		printf(" No access to boot partition\n");
+		break;
+	case 0x1:
+		printf(" R/W Boot Partition 1\n");
+		break;
+	case 0x2:
+		printf(" R/W Boot Partition 2\n");
+		break;
+	case 0x3:
+		printf(" R/W Replay Protected Memory Block (RPMB)\n");
+		break;
+	default:
+		printf(" Access to General Purpose partition %d\n",
+			(reg & EXT_CSD_BOOT_CFG_ACC) - 3);
+		break;
+	}
+
+	printf("Boot config protection [BOOT_CONFIG_PROT: 0x%02x]\n",
+		ext_csd[178]);
+	printf("Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x%02x]\n",
+		ext_csd[177]);
+	printf("High-density erase group definition"
+		" [ERASE_GROUP_DEF: 0x%02x]\n", ext_csd[EXT_CSD_ERASE_GROUP_DEF]);
+
+	print_writeprotect_boot_status(ext_csd);
+
+	if (ext_csd_rev >= 5) {
+		/* A441]: reserved [172] */
+		printf("User area write protection register"
+			" [USER_WP]: 0x%02x\n", ext_csd[171]);
+		/* A441]: reserved [170] */
+		printf("FW configuration [FW_CONFIG]: 0x%02x\n", ext_csd[169]);
+		printf("RPMB Size [RPMB_SIZE_MULT]: 0x%02x\n", ext_csd[168]);
+
+		reg = ext_csd[EXT_CSD_WR_REL_SET];
+		const char * const fast = "existing data is at risk if a power "
+				"failure occurs during a write operation";
+		const char * const reliable = "the device protects existing "
+				"data if a power failure occurs during a write "
+				"operation";
+		printf("Write reliability setting register"
+			" [WR_REL_SET]: 0x%02x\n", reg);
+
+		printf(" user area: %s\n", reg & (1<<0) ? reliable : fast);
+		int i;
+		for (i = 1; i <= 4; i++) {
+			printf(" partition %d: %s\n", i,
+				reg & (1<<i) ? reliable : fast);
+		}
+
+		reg = ext_csd[EXT_CSD_WR_REL_PARAM];
+		printf("Write reliability parameter register"
+			" [WR_REL_PARAM]: 0x%02x\n", reg);
+		if (reg & 0x01)
+			printf(" Device supports writing EXT_CSD_WR_REL_SET\n");
+		if (reg & 0x04)
+			printf(" Device supports the enhanced def. of reliable "
+				"write\n");
+
+		/* sanitize_start ext_csd[165]]: not readable
+		 * bkops_start ext_csd[164]]: only writable */
+		printf("Enable background operations handshake"
+			" [BKOPS_EN]: 0x%02x\n", ext_csd[163]);
+		printf("H/W reset function"
+			" [RST_N_FUNCTION]: 0x%02x\n", ext_csd[162]);
+		printf("HPI management [HPI_MGMT]: 0x%02x\n", ext_csd[161]);
+		reg = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
+		printf("Partitioning Support [PARTITIONING_SUPPORT]: 0x%02x\n",
+			reg);
+		if (reg & EXT_CSD_PARTITIONING_EN)
+			printf(" Device support partitioning feature\n");
+		else
+			printf(" Device NOT support partitioning feature\n");
+		if (reg & EXT_CSD_ENH_ATTRIBUTE_EN)
+			printf(" Device can have enhanced tech.\n");
+		else
+			printf(" Device cannot have enhanced tech.\n");
+
+		regl = (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_2] << 16) |
+			(ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_1] << 8) |
+			ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_0];
+
+		printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n",
+			   regl);
+		unsigned int wp_sz = get_hc_wp_grp_size(ext_csd);
+		unsigned int erase_sz = get_hc_erase_grp_size(ext_csd);
+		printf(" i.e. %lu KiB\n", 512l * regl * wp_sz * erase_sz);
+
+		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
+			ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]);
+		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
+		printf("Partitioning Setting"
+			" [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
+			reg);
+		if (reg)
+			printf(" Device partition setting complete\n");
+		else
+			printf(" Device partition setting NOT complete\n");
+
+		printf("General Purpose Partition Size\n"
+			" [GP_SIZE_MULT_4]: 0x%06x\n", (ext_csd[154] << 16) |
+			(ext_csd[153] << 8) | ext_csd[152]);
+		printf(" [GP_SIZE_MULT_3]: 0x%06x\n", (ext_csd[151] << 16) |
+			   (ext_csd[150] << 8) | ext_csd[149]);
+		printf(" [GP_SIZE_MULT_2]: 0x%06x\n", (ext_csd[148] << 16) |
+			   (ext_csd[147] << 8) | ext_csd[146]);
+		printf(" [GP_SIZE_MULT_1]: 0x%06x\n", (ext_csd[145] << 16) |
+			   (ext_csd[144] << 8) | ext_csd[143]);
+
+		regl =	(ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) |
+			ext_csd[EXT_CSD_ENH_SIZE_MULT_0];
+		printf("Enhanced User Data Area Size"
+			" [ENH_SIZE_MULT]: 0x%06x\n", regl);
+		printf(" i.e. %lu KiB\n", 512l * regl *
+		       get_hc_erase_grp_size(ext_csd) *
+		       get_hc_wp_grp_size(ext_csd));
+
+		regl =	(ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_1] << 8) |
+			ext_csd[EXT_CSD_ENH_START_ADDR_0];
+		printf("Enhanced User Data Start Address"
+			" [ENH_START_ADDR]: 0x%08x\n", regl);
+		printf(" i.e. %llu bytes offset\n", (is_blockaddresed(ext_csd) ?
+				512ll : 1ll) * regl);
+
+		/* A441]: reserved [135] */
+		printf("Bad Block Management mode"
+			" [SEC_BAD_BLK_MGMNT]: 0x%02x\n", ext_csd[134]);
+		/* A441: reserved [133:0] */
+	}
+	/* B45 */
+	if (ext_csd_rev >= 6) {
+		int j;
+		/* tcase_support ext_csd[132] not readable */
+		printf("Periodic Wake-up [PERIODIC_WAKEUP]: 0x%02x\n",
+			ext_csd[131]);
+		printf("Program CID/CSD in DDR mode support"
+			" [PROGRAM_CID_CSD_DDR_SUPPORT]: 0x%02x\n",
+			   ext_csd[130]);
+
+		for (j = 127; j >= 64; j--)
+			printf("Vendor Specific Fields"
+				" [VENDOR_SPECIFIC_FIELD[%d]]: 0x%02x\n",
+				j, ext_csd[j]);
+
+		printf("Native sector size [NATIVE_SECTOR_SIZE]: 0x%02x\n",
+			ext_csd[63]);
+		printf("Sector size emulation [USE_NATIVE_SECTOR]: 0x%02x\n",
+			ext_csd[62]);
+		printf("Sector size [DATA_SECTOR_SIZE]: 0x%02x\n", ext_csd[61]);
+		printf("1st initialization after disabling sector"
+			" size emulation [INI_TIMEOUT_EMU]: 0x%02x\n",
+			ext_csd[60]);
+		printf("Class 6 commands control [CLASS_6_CTRL]: 0x%02x\n",
+			ext_csd[59]);
+		printf("Number of addressed group to be Released"
+			"[DYNCAP_NEEDED]: 0x%02x\n", ext_csd[58]);
+		printf("Exception events control"
+			" [EXCEPTION_EVENTS_CTRL]: 0x%04x\n",
+			(ext_csd[57] << 8) | ext_csd[56]);
+		printf("Exception events status"
+			"[EXCEPTION_EVENTS_STATUS]: 0x%04x\n",
+			(ext_csd[55] << 8) | ext_csd[54]);
+		printf("Extended Partitions Attribute"
+			" [EXT_PARTITIONS_ATTRIBUTE]: 0x%04x\n",
+			(ext_csd[53] << 8) | ext_csd[52]);
+
+		for (j = 51; j >= 37; j--)
+			printf("Context configuration"
+				" [CONTEXT_CONF[%d]]: 0x%02x\n", j, ext_csd[j]);
+
+		printf("Packed command status"
+			" [PACKED_COMMAND_STATUS]: 0x%02x\n", ext_csd[36]);
+		printf("Packed command failure index"
+			" [PACKED_FAILURE_INDEX]: 0x%02x\n", ext_csd[35]);
+		printf("Power Off Notification"
+			" [POWER_OFF_NOTIFICATION]: 0x%02x\n", ext_csd[34]);
+		printf("Control to turn the Cache ON/OFF"
+			" [CACHE_CTRL]: 0x%02x\n", ext_csd[33]);
+		/* flush_cache ext_csd[32] not readable */
+		/*Reserved [31:0] */
+	}
+
+	if (ext_csd_rev >= 7) {
+		printf("eMMC Firmware Version: %s\n",
+			(char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION]);
+		printf("eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x%02x\n",
+			ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]);
+		printf("eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x%02x\n",
+			ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]);
+		printf("eMMC Pre EOL information [EXT_CSD_PRE_EOL_INFO]: 0x%02x\n",
+			ext_csd[EXT_CSD_PRE_EOL_INFO]);
+		reg = ext_csd[EXT_CSD_SECURE_REMOVAL_TYPE];
+		printf("Secure Removal Type [SECURE_REMOVAL_TYPE]: 0x%02x\n", reg);
+		printf(" information is configured to be removed ");
+		/* Bit [5:4]: Configure Secure Removal Type */
+		switch ((reg & EXT_CSD_CONFIG_SECRM_TYPE) >> 4) {
+			case 0x0:
+				printf("by an erase of the physical memory\n");
+				break;
+			case 0x1:
+				printf("by an overwriting the addressed locations"
+				       " with a character followed by an erase\n");
+				break;
+			case 0x2:
+				printf("by an overwriting the addressed locations"
+				       " with a character, its complement, then a random character\n");
+				break;
+			case 0x3:
+				printf("using a vendor defined\n");
+				break;
+		}
+		/* Bit [3:0]: Supported Secure Removal Type */
+		printf(" Supported Secure Removal Type:\n");
+		if (reg & 0x01)
+			printf("  information removed by an erase of the physical memory\n");
+		if (reg & 0x02)
+			printf("  information removed by an overwriting the addressed locations"
+			       " with a character followed by an erase\n");
+		if (reg & 0x04)
+			printf("  information removed by an overwriting the addressed locations"
+			       " with a character, its complement, then a random character\n");
+		if (reg & 0x08)
+			printf("  information removed using a vendor defined\n");
+	}
+
+	if (ext_csd_rev >= 8) {
+		printf("Command Queue Support [CMDQ_SUPPORT]: 0x%02x\n",
+		       ext_csd[EXT_CSD_CMDQ_SUPPORT]);
+		printf("Command Queue Depth [CMDQ_DEPTH]: %u\n",
+		       (ext_csd[EXT_CSD_CMDQ_DEPTH] & 0x1f) + 1);
+		printf("Command Enabled [CMDQ_MODE_EN]: 0x%02x\n",
+		       ext_csd[EXT_CSD_CMDQ_MODE_EN]);
+	}
+out_free:
+	return ret;
+}
+
+int do_sanitize(int nargs, char **argv)
+{
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc sanitize </path/to/mmcblkX>\n");
+		exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = write_extcsd_value(fd, EXT_CSD_SANITIZE_START, 1);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			1, EXT_CSD_SANITIZE_START, device);
+		exit(1);
+	}
+
+	return ret;
+
+}
+
+#define DO_IO(func, fd, buf, nbyte)					\
+	({												\
+		ssize_t ret = 0, r;							\
+		do {										\
+			r = func(fd, buf + ret, nbyte - ret);	\
+			if (r < 0 && errno != EINTR) {			\
+				ret = -1;							\
+				break;								\
+			}										\
+			else if (r > 0)							\
+				ret += r;							\
+		} while (r != 0 && (size_t)ret != nbyte);	\
+													\
+		ret;										\
+	})
+
+#define RPMB_MULTI_CMD_MAX_CMDS 3
+
+enum rpmb_op_type {
+	MMC_RPMB_WRITE_KEY = 0x01,
+	MMC_RPMB_READ_CNT  = 0x02,
+	MMC_RPMB_WRITE     = 0x03,
+	MMC_RPMB_READ      = 0x04,
+
+	/* For internal usage only, do not use it directly */
+	MMC_RPMB_READ_RESP = 0x05
+};
+
+struct rpmb_frame {
+	u_int8_t  stuff[196];
+	u_int8_t  key_mac[32];
+	u_int8_t  data[256];
+	u_int8_t  nonce[16];
+	u_int32_t write_counter;
+	u_int16_t addr;
+	u_int16_t block_count;
+	u_int16_t result;
+	u_int16_t req_resp;
+};
+
+static inline void set_single_cmd(struct mmc_ioc_cmd *ioc, __u32 opcode,
+				  int write_flag, unsigned int blocks)
+{
+	ioc->opcode = opcode;
+	ioc->write_flag = write_flag;
+	ioc->arg = 0x0;
+	ioc->blksz = 512;
+	ioc->blocks = blocks;
+	ioc->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+}
+
+/* Performs RPMB operation.
+ *
+ * @fd: RPMB device on which we should perform ioctl command
+ * @frame_in: input RPMB frame, should be properly inited
+ * @frame_out: output (result) RPMB frame. Caller is responsible for checking
+ *             result and req_resp for output frame.
+ * @out_cnt: count of outer frames. Used only for multiple blocks reading,
+ *           in the other cases -EINVAL will be returned.
+ */
+int do_rpmb_op(int fd,
+					  const struct rpmb_frame *frame_in,
+					  struct rpmb_frame *frame_out,
+					  unsigned int out_cnt)
+{
+#ifndef MMC_IOC_MULTI_CMD
+	fprintf(stderr, "mmc-utils has been compiled without MMC_IOC_MULTI_CMD"
+		" support, needed by RPMB operation.\n");
+	exit(1);
+#else
+	int err;
+	u_int16_t rpmb_type;
+	struct mmc_ioc_multi_cmd *mioc;
+	struct mmc_ioc_cmd *ioc;
+	struct rpmb_frame frame_status = {0};
+
+	if (!frame_in || !frame_out || !out_cnt)
+		return -EINVAL;
+
+	/* prepare arguments for MMC_IOC_MULTI_CMD ioctl */
+	mioc = (struct mmc_ioc_multi_cmd *)
+		malloc(sizeof (struct mmc_ioc_multi_cmd) +
+		       RPMB_MULTI_CMD_MAX_CMDS * sizeof (struct mmc_ioc_cmd));
+	if (!mioc) {
+		return -ENOMEM;
+	}
+
+	rpmb_type = be16toh(frame_in->req_resp);
+
+	switch(rpmb_type) {
+	case MMC_RPMB_WRITE:
+	case MMC_RPMB_WRITE_KEY:
+		if (out_cnt != 1) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		mioc->num_of_cmds = 3;
+
+		/* Write request */
+		ioc = &mioc->cmds[0];
+		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, (1 << 31) | 1, 1);
+		mmc_ioc_cmd_set_data((*ioc), frame_in);
+
+		/* Result request */
+		ioc = &mioc->cmds[1];
+		frame_status.req_resp = htobe16(MMC_RPMB_READ_RESP);
+		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
+		mmc_ioc_cmd_set_data((*ioc), &frame_status);
+
+		/* Get response */
+		ioc = &mioc->cmds[2];
+		set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, 1);
+		mmc_ioc_cmd_set_data((*ioc), frame_out);
+
+		break;
+	case MMC_RPMB_READ_CNT:
+		if (out_cnt != 1) {
+			err = -EINVAL;
+			goto out;
+		}
+		/* fall through */
+
+	case MMC_RPMB_READ:
+		mioc->num_of_cmds = 2;
+
+		/* Read request */
+		ioc = &mioc->cmds[0];
+		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
+		mmc_ioc_cmd_set_data((*ioc), frame_in);
+
+		/* Get response */
+		ioc = &mioc->cmds[1];
+		set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, out_cnt);
+		mmc_ioc_cmd_set_data((*ioc), frame_out);
+
+		break;
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+
+	err = ioctl(fd, MMC_IOC_MULTI_CMD, mioc);
+
+out:
+	free(mioc);
+	return err;
+#endif /* !MMC_IOC_MULTI_CMD */
+}
+
+int do_rpmb_write_key(int nargs, char **argv)
+{
+	int ret, dev_fd, key_fd;
+	struct rpmb_frame frame_in = {
+		.req_resp = htobe16(MMC_RPMB_WRITE_KEY)
+	}, frame_out;
+
+	if (nargs != 3) {
+		fprintf(stderr, "Usage: mmc rpmb write-key </path/to/mmcblkXrpmb> </path/to/key>\n");
+		exit(1);
+	}
+
+	dev_fd = open(argv[1], O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open");
+		exit(1);
+	}
+
+	if (0 == strcmp(argv[2], "-"))
+		key_fd = STDIN_FILENO;
+	else {
+		key_fd = open(argv[2], O_RDONLY);
+		if (key_fd < 0) {
+			perror("can't open key file");
+			exit(1);
+		}
+	}
+
+	/* Read the auth key */
+	ret = DO_IO(read, key_fd, frame_in.key_mac, sizeof(frame_in.key_mac));
+	if (ret < 0) {
+		perror("read the key");
+		exit(1);
+	} else if (ret != sizeof(frame_in.key_mac)) {
+		printf("Auth key must be %lu bytes length, but we read only %d, exit\n",
+			   (unsigned long)sizeof(frame_in.key_mac),
+			   ret);
+		exit(1);
+	}
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, &frame_out, 1);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out.result != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n",
+			   be16toh(frame_out.result));
+		exit(1);
+	}
+
+	close(dev_fd);
+	if (key_fd != STDIN_FILENO)
+		close(key_fd);
+
+	return ret;
+}
+
+int rpmb_read_counter(int dev_fd, unsigned int *cnt)
+{
+	int ret;
+	struct rpmb_frame frame_in = {
+		.req_resp = htobe16(MMC_RPMB_READ_CNT)
+	}, frame_out;
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, &frame_out, 1);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out.result != 0)
+		return be16toh(frame_out.result);
+
+	*cnt = be32toh(frame_out.write_counter);
+
+	return 0;
+}
+
+int do_rpmb_read_counter(int nargs, char **argv)
+{
+	int ret, dev_fd;
+	unsigned int cnt;
+
+	if (nargs != 2) {
+		fprintf(stderr, "Usage: mmc rpmb read-counter </path/to/mmcblkXrpmb>\n");
+		exit(1);
+	}
+
+	dev_fd = open(argv[1], O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open");
+		exit(1);
+	}
+
+	ret = rpmb_read_counter(dev_fd, &cnt);
+
+	/* Check RPMB response */
+	if (ret != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n", ret);
+		exit(1);
+	}
+
+	close(dev_fd);
+
+	printf("Counter value: 0x%08x\n", cnt);
+
+	return ret;
+}
+
+int do_rpmb_read_block(int nargs, char **argv)
+{
+	int i, ret, dev_fd, data_fd, key_fd = -1;
+	uint16_t addr;
+	/*
+	 * for reading RPMB, number of blocks is set by CMD23 only, the packet
+	 * frame field for that is set to 0. So, the type is not u16 but uint!
+	 */
+	unsigned int blocks_cnt;
+	unsigned char key[32];
+	struct rpmb_frame frame_in = {
+		.req_resp    = htobe16(MMC_RPMB_READ),
+	}, *frame_out_p;
+
+	if (nargs != 5 && nargs != 6) {
+		fprintf(stderr, "Usage: mmc rpmb read-block </path/to/mmcblkXrpmb> <address> <blocks count> </path/to/output_file> [/path/to/key]\n");
+		exit(1);
+	}
+
+	dev_fd = open(argv[1], O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open");
+		exit(1);
+	}
+
+	/* Get block address */
+	errno = 0;
+	addr = strtol(argv[2], NULL, 0);
+	if (errno) {
+		perror("incorrect address");
+		exit(1);
+	}
+	frame_in.addr = htobe16(addr);
+
+	/* Get blocks count */
+	errno = 0;
+	blocks_cnt = strtol(argv[3], NULL, 0);
+	if (errno) {
+		perror("incorrect blocks count");
+		exit(1);
+	}
+
+	if (!blocks_cnt) {
+		printf("please, specify valid blocks count number\n");
+		exit(1);
+	}
+
+	frame_out_p = calloc(sizeof(*frame_out_p), blocks_cnt);
+	if (!frame_out_p) {
+		printf("can't allocate memory for RPMB outer frames\n");
+		exit(1);
+	}
+
+	/* Write 256b data */
+	if (0 == strcmp(argv[4], "-"))
+		data_fd = STDOUT_FILENO;
+	else {
+		data_fd = open(argv[4], O_WRONLY | O_CREAT | O_APPEND,
+					   S_IRUSR | S_IWUSR);
+		if (data_fd < 0) {
+			perror("can't open output file");
+			exit(1);
+		}
+	}
+
+	/* Key is specified */
+	if (nargs == 6) {
+		if (0 == strcmp(argv[5], "-"))
+			key_fd = STDIN_FILENO;
+		else {
+			key_fd = open(argv[5], O_RDONLY);
+			if (key_fd < 0) {
+				perror("can't open input key file");
+				exit(1);
+			}
+		}
+
+		ret = DO_IO(read, key_fd, key, sizeof(key));
+		if (ret < 0) {
+			perror("read the key data");
+			exit(1);
+		} else if (ret != sizeof(key)) {
+			printf("Data must be %lu bytes length, but we read only %d, exit\n",
+				   (unsigned long)sizeof(key),
+				   ret);
+			exit(1);
+		}
+	}
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, frame_out_p, blocks_cnt);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out_p[blocks_cnt - 1].result != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n",
+			   be16toh(frame_out_p[blocks_cnt - 1].result));
+		exit(1);
+	}
+
+	/* Do we have to verify data against key? */
+	if (nargs == 6) {
+		unsigned char mac[32];
+		hmac_sha256_ctx ctx;
+		struct rpmb_frame *frame_out = NULL;
+
+		hmac_sha256_init(&ctx, key, sizeof(key));
+		for (i = 0; i < blocks_cnt; i++) {
+			frame_out = &frame_out_p[i];
+			hmac_sha256_update(&ctx, frame_out->data,
+							   sizeof(*frame_out) -
+								   offsetof(struct rpmb_frame, data));
+		}
+
+		hmac_sha256_final(&ctx, mac, sizeof(mac));
+
+		/* Impossible */
+		assert(frame_out);
+
+		/* Compare calculated MAC and MAC from last frame */
+		if (memcmp(mac, frame_out->key_mac, sizeof(mac))) {
+			printf("RPMB MAC missmatch\n");
+			exit(1);
+		}
+	}
+
+	/* Write data */
+	for (i = 0; i < blocks_cnt; i++) {
+		struct rpmb_frame *frame_out = &frame_out_p[i];
+		ret = DO_IO(write, data_fd, frame_out->data, sizeof(frame_out->data));
+		if (ret < 0) {
+			perror("write the data");
+			exit(1);
+		} else if (ret != sizeof(frame_out->data)) {
+			printf("Data must be %lu bytes length, but we wrote only %d, exit\n",
+				   (unsigned long)sizeof(frame_out->data),
+				   ret);
+			exit(1);
+		}
+	}
+
+	free(frame_out_p);
+	close(dev_fd);
+	if (data_fd != STDOUT_FILENO)
+		close(data_fd);
+	if (key_fd != -1 && key_fd != STDIN_FILENO)
+		close(key_fd);
+
+	return ret;
+}
+
+int do_rpmb_write_block(int nargs, char **argv)
+{
+	int ret, dev_fd, key_fd, data_fd;
+	unsigned char key[32];
+	uint16_t addr;
+	unsigned int cnt;
+	struct rpmb_frame frame_in = {
+		.req_resp    = htobe16(MMC_RPMB_WRITE),
+		.block_count = htobe16(1)
+	}, frame_out;
+
+	if (nargs != 5) {
+		fprintf(stderr, "Usage: mmc rpmb write-block </path/to/mmcblkXrpmb> <address> </path/to/input_file> </path/to/key>\n");
+		exit(1);
+	}
+
+	dev_fd = open(argv[1], O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open");
+		exit(1);
+	}
+
+	ret = rpmb_read_counter(dev_fd, &cnt);
+	/* Check RPMB response */
+	if (ret != 0) {
+		printf("RPMB read counter operation failed, retcode 0x%04x\n", ret);
+		exit(1);
+	}
+	frame_in.write_counter = htobe32(cnt);
+
+	/* Get block address */
+	errno = 0;
+	addr = strtol(argv[2], NULL, 0);
+	if (errno) {
+		perror("incorrect address");
+		exit(1);
+	}
+	frame_in.addr = htobe16(addr);
+
+	/* Read 256b data */
+	if (0 == strcmp(argv[3], "-"))
+		data_fd = STDIN_FILENO;
+	else {
+		data_fd = open(argv[3], O_RDONLY);
+		if (data_fd < 0) {
+			perror("can't open input file");
+			exit(1);
+		}
+	}
+
+	ret = DO_IO(read, data_fd, frame_in.data, sizeof(frame_in.data));
+	if (ret < 0) {
+		perror("read the data");
+		exit(1);
+	} else if (ret != sizeof(frame_in.data)) {
+		printf("Data must be %lu bytes length, but we read only %d, exit\n",
+			   (unsigned long)sizeof(frame_in.data),
+			   ret);
+		exit(1);
+	}
+
+	/* Read the auth key */
+	if (0 == strcmp(argv[4], "-"))
+		key_fd = STDIN_FILENO;
+	else {
+		key_fd = open(argv[4], O_RDONLY);
+		if (key_fd < 0) {
+			perror("can't open key file");
+			exit(1);
+		}
+	}
+
+	ret = DO_IO(read, key_fd, key, sizeof(key));
+	if (ret < 0) {
+		perror("read the key");
+		exit(1);
+	} else if (ret != sizeof(key)) {
+		printf("Auth key must be %lu bytes length, but we read only %d, exit\n",
+			   (unsigned long)sizeof(key),
+			   ret);
+		exit(1);
+	}
+
+	/* Calculate HMAC SHA256 */
+	hmac_sha256(
+		key, sizeof(key),
+		frame_in.data, sizeof(frame_in) - offsetof(struct rpmb_frame, data),
+		frame_in.key_mac, sizeof(frame_in.key_mac));
+
+	/* Execute RPMB op */
+	ret = do_rpmb_op(dev_fd, &frame_in, &frame_out, 1);
+	if (ret != 0) {
+		perror("RPMB ioctl failed");
+		exit(1);
+	}
+
+	/* Check RPMB response */
+	if (frame_out.result != 0) {
+		printf("RPMB operation failed, retcode 0x%04x\n",
+			   be16toh(frame_out.result));
+		exit(1);
+	}
+
+	close(dev_fd);
+	if (data_fd != STDIN_FILENO)
+		close(data_fd);
+	if (key_fd != STDIN_FILENO)
+		close(key_fd);
+
+	return ret;
+}
+
+int do_cache_ctrl(int value, int nargs, char **argv)
+{
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+
+	if (nargs != 2) {
+	       fprintf(stderr, "Usage: mmc cache enable </path/to/mmcblkX>\n");
+	       exit(1);
+	}
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	if (ext_csd[EXT_CSD_REV] < EXT_CSD_REV_V4_5) {
+		fprintf(stderr,
+			"The CACHE option is only availabe on devices >= "
+			"MMC 4.5 %s\n", device);
+		exit(1);
+	}
+
+	/* If the cache size is zero, this device does not have a cache */
+	if (!(ext_csd[EXT_CSD_CACHE_SIZE_3] ||
+			ext_csd[EXT_CSD_CACHE_SIZE_2] ||
+			ext_csd[EXT_CSD_CACHE_SIZE_1] ||
+			ext_csd[EXT_CSD_CACHE_SIZE_0])) {
+		fprintf(stderr,
+			"The CACHE option is not available on %s\n",
+			device);
+		exit(1);
+	}
+	ret = write_extcsd_value(fd, EXT_CSD_CACHE_CTRL, value);
+	if (ret) {
+		fprintf(stderr,
+			"Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_CACHE_CTRL, device);
+		exit(1);
+	}
+
+	return ret;
+}
+
+int do_cache_en(int nargs, char **argv)
+{
+	return do_cache_ctrl(1, nargs, argv);
+}
+
+int do_cache_dis(int nargs, char **argv)
+{
+	return do_cache_ctrl(0, nargs, argv);
+}
+
+int do_ffu(int nargs, char **argv)
+{
+#ifndef MMC_IOC_MULTI_CMD
+	fprintf(stderr, "mmc-utils has been compiled without MMC_IOC_MULTI_CMD"
+			" support, needed by FFU.\n");
+	exit(1);
+#else
+	int dev_fd, img_fd;
+	int sect_done = 0, retry = 3, ret = -EINVAL;
+	unsigned int sect_size;
+	__u8 ext_csd[512];
+	__u8 *buf;
+	__u32 arg;
+	off_t fw_size;
+	ssize_t chunk_size;
+	char *device;
+	struct mmc_ioc_multi_cmd *multi_cmd;
+
+	if (nargs != 3) {
+		fprintf(stderr, "Usage: ffu <image name> </path/to/mmcblkX> \n");
+		exit(1);
+	}
+
+	device = argv[2];
+	dev_fd = open(device, O_RDWR);
+	if (dev_fd < 0) {
+		perror("device open failed");
+		exit(1);
+	}
+	img_fd = open(argv[1], O_RDONLY);
+	if (img_fd < 0) {
+		perror("image open failed");
+		close(dev_fd);
+		exit(1);
+	}
+
+	buf = malloc(512);
+	multi_cmd = calloc(1, sizeof(struct mmc_ioc_multi_cmd) +
+				3 * sizeof(struct mmc_ioc_cmd));
+	if (!buf || !multi_cmd) {
+		perror("failed to allocate memory");
+		goto out;
+	}
+
+	ret = read_extcsd(dev_fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		goto out;
+	}
+
+	if (ext_csd[EXT_CSD_REV] < EXT_CSD_REV_V5_0) {
+		fprintf(stderr,
+			"The FFU feature is only available on devices >= "
+			"MMC 5.0, not supported in %s\n", device);
+		goto out;
+	}
+
+	if (!(ext_csd[EXT_CSD_SUPPORTED_MODES] & EXT_CSD_FFU)) {
+		fprintf(stderr, "FFU is not supported in %s\n", device);
+		goto out;
+	}
+
+	if (ext_csd[EXT_CSD_FW_CONFIG] & EXT_CSD_UPDATE_DISABLE) {
+		fprintf(stderr, "Firmware update was disabled in %s\n", device);
+		goto out;
+	}
+
+	fw_size = lseek(img_fd, 0, SEEK_END);
+
+	if (fw_size == 0) {
+		fprintf(stderr, "Firmware image is empty");
+		goto out;
+	}
+
+	sect_size = (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 0) ? 512 : 4096;
+	if (fw_size % sect_size) {
+		fprintf(stderr, "Firmware data size (%jd) is not aligned!\n", (intmax_t)fw_size);
+		goto out;
+	}
+
+	/* set CMD ARG */
+	arg = ext_csd[EXT_CSD_FFU_ARG_0] |
+		ext_csd[EXT_CSD_FFU_ARG_1] << 8 |
+		ext_csd[EXT_CSD_FFU_ARG_2] << 16 |
+		ext_csd[EXT_CSD_FFU_ARG_3] << 24;
+
+	/* prepare multi_cmd to be sent */
+	multi_cmd->num_of_cmds = 3;
+
+	/* put device into ffu mode */
+	multi_cmd->cmds[0].opcode = MMC_SWITCH;
+	multi_cmd->cmds[0].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+			(EXT_CSD_MODE_CONFIG << 16) |
+			(EXT_CSD_FFU_MODE << 8) |
+			EXT_CSD_CMD_SET_NORMAL;
+	multi_cmd->cmds[0].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+	multi_cmd->cmds[0].write_flag = 1;
+
+	/* send image chunk */
+	multi_cmd->cmds[1].opcode = MMC_WRITE_BLOCK;
+	multi_cmd->cmds[1].blksz = sect_size;
+	multi_cmd->cmds[1].blocks = 1;
+	multi_cmd->cmds[1].arg = arg;
+	multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+	multi_cmd->cmds[1].write_flag = 1;
+	mmc_ioc_cmd_set_data(multi_cmd->cmds[1], buf);
+
+	/* return device into normal mode */
+	multi_cmd->cmds[2].opcode = MMC_SWITCH;
+	multi_cmd->cmds[2].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+			(EXT_CSD_MODE_CONFIG << 16) |
+			(EXT_CSD_NORMAL_MODE << 8) |
+			EXT_CSD_CMD_SET_NORMAL;
+	multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+	multi_cmd->cmds[2].write_flag = 1;
+
+do_retry:
+	/* read firmware chunk */
+	lseek(img_fd, 0, SEEK_SET);
+	chunk_size = read(img_fd, buf, 512);
+
+	while (chunk_size > 0) {
+		/* send ioctl with multi-cmd */
+		ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
+
+		if (ret) {
+			perror("Multi-cmd ioctl");
+			/* In case multi-cmd ioctl failed before exiting from ffu mode */
+			ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]);
+			goto out;
+		}
+
+		ret = read_extcsd(dev_fd, ext_csd);
+		if (ret) {
+			fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+			goto out;
+		}
+
+		/* Test if we need to restart the download */
+		sect_done = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0] |
+				ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_1] << 8 |
+				ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_2] << 16 |
+				ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_3] << 24;
+		/* By spec, host should re-start download from the first sector if sect_done is 0 */
+		if (sect_done == 0) {
+			if (retry > 0) {
+				retry--;
+				fprintf(stderr, "Programming failed. Retrying... (%d)\n", retry);
+				goto do_retry;
+			}
+			fprintf(stderr, "Programming failed! Aborting...\n");
+			goto out;
+		} else {
+			fprintf(stderr, "Programmed %d/%jd bytes\r", sect_done * sect_size, (intmax_t)fw_size);
+		}
+
+		/* read the next firmware chunk (if any) */
+		chunk_size = read(img_fd, buf, 512);
+	}
+
+	if ((sect_done * sect_size) == fw_size) {
+		fprintf(stderr, "Programmed %jd/%jd bytes\n", (intmax_t)fw_size, (intmax_t)fw_size);
+		fprintf(stderr, "Programming finished with status %d \n", ret);
+	}
+	else {
+		fprintf(stderr, "FW size and number of sectors written mismatch. Status return %d\n", ret);
+		goto out;
+	}
+
+	/* check mode operation for ffu install*/
+	if (!ext_csd[EXT_CSD_FFU_FEATURES]) {
+		fprintf(stderr, "Please reboot to complete firmware installation on %s\n", device);
+	} else {
+		fprintf(stderr, "Installing firmware on %s...\n", device);
+		/* Re-enter ffu mode and install the firmware */
+		multi_cmd->num_of_cmds = 2;
+
+		/* set ext_csd to install mode */
+		multi_cmd->cmds[1].opcode = MMC_SWITCH;
+		multi_cmd->cmds[1].blksz = 0;
+		multi_cmd->cmds[1].blocks = 0;
+		multi_cmd->cmds[1].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+				(EXT_CSD_MODE_OPERATION_CODES << 16) |
+				(EXT_CSD_FFU_INSTALL << 8) |
+				EXT_CSD_CMD_SET_NORMAL;
+		multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+		multi_cmd->cmds[1].write_flag = 1;
+
+		/* send ioctl with multi-cmd */
+		ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
+
+		if (ret) {
+			perror("Multi-cmd ioctl failed setting install mode");
+			/* In case multi-cmd ioctl failed before exiting from ffu mode */
+			ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]);
+			goto out;
+		}
+
+		ret = read_extcsd(dev_fd, ext_csd);
+		if (ret) {
+			fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+			goto out;
+		}
+
+		/* return status */
+		ret = ext_csd[EXT_CSD_FFU_STATUS];
+		if (ret) {
+			fprintf(stderr, "%s: error %d during FFU install:\n", device, ret);
+			goto out;
+		} else {
+			fprintf(stderr, "FFU finished successfully\n");
+		}
+	}
+
+out:
+	free(buf);
+	free(multi_cmd);
+	close(img_fd);
+	close(dev_fd);
+	return ret;
+#endif
+}

+ 47 - 0
emmc_hal_lib/mmc-utils/mmc_cmds.h

@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Modified to add field firmware update support,
+ * those modifications are Copyright (c) 2016 SanDisk Corp.
+ */
+
+/* mmc_cmds.c */
+int do_read_extcsd(int nargs, char **argv);
+int do_write_extcsd(int nargs, char **argv);
+int do_writeprotect_boot_get(int nargs, char **argv);
+int do_writeprotect_boot_set(int nargs, char **argv);
+int do_writeprotect_user_get(int nargs, char **argv);
+int do_writeprotect_user_set(int nargs, char **argv);
+int do_disable_512B_emulation(int nargs, char **argv);
+int do_write_boot_en(int nargs, char **argv);
+int do_boot_bus_conditions_set(int nargs, char **argv);
+int do_write_bkops_en(int nargs, char **argv);
+int do_hwreset_en(int nargs, char **argv);
+int do_hwreset_dis(int nargs, char **argv);
+int do_sanitize(int nargs, char **argv);
+int do_status_get(int nargs, char **argv);
+int do_create_gp_partition(int nargs, char **argv);
+int do_enh_area_set(int nargs, char **argv);
+int do_write_reliability_set(int nargs, char **argv);
+int do_rpmb_write_key(int nargs, char **argv);
+int do_rpmb_read_counter(int nargs, char **argv);
+int do_rpmb_read_block(int nargs, char **argv);
+int do_rpmb_write_block(int nargs, char **argv);
+int do_cache_en(int nargs, char **argv);
+int do_cache_dis(int nargs, char **argv);
+int do_ffu(int nargs, char **argv);
+int do_read_scr(int argc, char **argv);
+int do_read_cid(int argc, char **argv);
+int do_read_csd(int argc, char **argv);

BIN
emmc_hal_lib/mmc-utils/rpmb_test.png


+ 22 - 0
iopmp_hal_lib/Makefile

@@ -0,0 +1,22 @@
+CC=$(CROSS)gcc
+CFLAGS:=-fpic
+LDFLAGS:=-shared -fpic
+SOURCE:=$(wildcard *.c)
+OBJS:=$(patsubst %.c,%.o,$(SOURCE))
+OUTDIR=./output
+TARGET_LIB:=libiopmp.so
+
+
+all:$(OBJS)
+	echo $(OBJS)
+	mkdir -p $(OUTDIR)
+	$(CC) $(LDFLAGS) -o $(OUTDIR)/$(TARGET_LIB) $(OBJS)
+
+%.o:%.c
+	@echo Compiling $< ...
+	$(CC) -c $(CFLAGS) $< -o $*.o
+
+.PHONY: clean
+
+clean:
+	rm -rf $(OUTDIR)/$(TARGET_LIB) *.o

+ 126 - 0
iopmp_hal_lib/light-iopmp-hal.c

@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "light-iopmp.h"
+
+static const char *light_iopmp_tap = "/sys/devices/platform/iopmp/light_iopmp_tap";
+static const char *light_iopmp_start_addr = "/sys/devices/platform/iopmp/light_iopmp_start_addr";
+static const char *light_iopmp_end_addr = "/sys/devices/platform/iopmp/light_iopmp_end_addr";
+static const char *light_iopmp_attr = "/sys/devices/platform/iopmp/light_iopmp_attr";
+static const char *light_iopmp_lock = "/sys/devices/platform/iopmp/light_iopmp_lock";
+static const char *light_iopmp_set = "/sys/devices/platform/iopmp/light_iopmp_set";
+
+/**
+ * @brief Light iopmp region permission setting.
+ *
+ * @param type
+ * @param attr
+ * @return csi_err_t
+ */
+int csi_iopmp_set_attr(int type, u_int8_t *start_addr, u_int8_t *end_addr, csi_iopmp_attr_t attr)
+{
+	int ret = 0;
+	int light_iopmp_tap_fd, light_iopmp_start_addr_fd, light_iopmp_end_addr_fd;
+	int light_iopmp_attr_fd, light_iopmp_lock_fd, light_iopmp_set_fd;
+
+	light_iopmp_tap_fd = open(light_iopmp_tap, O_RDWR);
+	if (light_iopmp_tap_fd < 0) {
+		perror("open tap");
+		exit(1);
+	} else {
+		char string[5];
+		sprintf(string, "%d\n", type);
+		if (write(light_iopmp_tap_fd, string, 5) != 5)
+			perror("write(tap)");
+		close(light_iopmp_tap_fd);
+	}
+
+	light_iopmp_start_addr_fd = open(light_iopmp_start_addr, O_RDWR);
+	if (light_iopmp_start_addr_fd < 0) {
+		perror("open start_addr");
+		exit(1);
+	} else {
+		char string[20];
+		int start = (int)((int64_t)start_addr >> 12);
+		sprintf(string, "%d\n", start);
+		if (write(light_iopmp_start_addr_fd, string, 20) != 20)
+			perror("write(start_addr)");
+		close(light_iopmp_start_addr_fd);
+	}
+
+	light_iopmp_end_addr_fd = open(light_iopmp_end_addr, O_RDWR);
+	if (light_iopmp_end_addr_fd < 0) {
+		perror("open end_addr");
+		exit(1);
+	} else {
+		int end = (int)((int64_t)end_addr >> 12);
+		char string[20];
+		sprintf(string, "%d\n", end);
+		if (write(light_iopmp_end_addr_fd, string, 20) != 20)
+			perror("write(end_addr)");
+		close(light_iopmp_end_addr_fd);
+	}
+
+	light_iopmp_attr_fd = open(light_iopmp_attr, O_RDWR);
+	if (light_iopmp_attr_fd < 0) {
+		perror("open attr");
+		exit(1);
+	} else {
+		char string[20];
+		sprintf(string, "%d\n", attr);
+		if (write(light_iopmp_attr_fd, string, 20) != 20)
+			perror("write(attr)");
+		close(light_iopmp_attr_fd);
+	}
+
+	light_iopmp_lock_fd = open(light_iopmp_lock, O_RDWR);
+	if (light_iopmp_lock_fd < 0) {
+		perror("open lock");
+		exit(1);
+	} else {
+		if (write(light_iopmp_lock_fd, "1\n", 2) != 2)
+			perror("write(lock)");
+		close(light_iopmp_lock_fd);
+	}
+
+	light_iopmp_set_fd = open(light_iopmp_set, O_WRONLY);
+	if (light_iopmp_set_fd < 0) {
+		perror("open set");
+		exit(1);
+	} else {
+		if (write(light_iopmp_set_fd, "1\n", 2) != 2)
+			perror("write(set)");
+		close(light_iopmp_set_fd);
+	}
+
+	return ret;
+}
+
+/** iopmp lock
+ * @brief  Lock secure iopmp setting.
+ *
+ * @return csi_err_t
+ */
+int csi_iopmp_lock(void)
+{
+	/* dummy API, csi_iopmp_set_attr() should lock iopmp */
+	return 0;
+}
+
+#if 0 /* demo */
+int main(int argc, char *argv[])
+{
+	csi_iopmp_set_attr(2, (u_int8_t *)0x0, (u_int8_t *)0x200000000, 0xffff);
+	return 1;
+}
+#endif

+ 59 - 0
iopmp_hal_lib/light-iopmp.h

@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#ifndef _LIGHT_IOPMP_API_H
+#define _LIGHT_IOPMP_API_H
+
+#define IOPMP_EMMC      0
+#define IOPMP_SDIO0     1
+#define IOPMP_SDIO1     2
+#define IOPMP_USB0      3
+#define IOPMP_AO        4
+#define IOPMP_AUD       5
+#define IOPMP_CHIP_DBG  6
+#define IOPMP_EIP120I   7
+#define IOPMP_EIP120II  8
+#define IOPMP_EIP120III 9
+#define IOPMP_ISP0      10
+#define IOPMP_ISP1      11
+#define IOPMP_DW200	12
+#define IOPMP_VIPRE     13
+#define IOPMP_VENC      14
+#define IOPMP_VDEC      15
+#define IOPMP_G2D       16
+#define IOPMP_FCE       17
+#define IOPMP_NPU       18
+#define IOPMP0_DPU      19
+#define IOPMP1_DPU      20
+#define IOPMP_GPU       21
+#define IOPMP_GMAC1     22
+#define IOPMP_GMAC2     23
+#define IOPMP_DMAC      24
+#define IOPMP_TEE_DMAC  25
+#define IOPMP_DSP0	26
+#define IOPMP_DSP1	27
+
+typedef enum {
+	CSI_ATTR_R	= 1,
+	CSI_ATTR_W	= 2,
+} csi_iopmp_attr_t;
+
+/**
+ * @brief Light iopmp region permission setting.
+ *
+ * @param type
+ * @param attr
+ * @return csi_err_t
+ */
+int csi_iopmp_set_attr(int type, u_int8_t *start_addr, u_int8_t *end_addr, csi_iopmp_attr_t attr);
+
+/** iopmp lock
+ * @brief  Lock secure iopmp setting.
+ *
+ * @return csi_err_t
+ */
+int csi_iopmp_lock(void);
+
+#endif

BIN
iopmp_hal_lib/output/libiopmp.so


+ 57 - 0
iopmp_hal_lib/output/light-iopmp.h

@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ *
+ */
+#ifndef _LIGHT_IOPMP_API_H
+#define _LIGHT_IOPMP_API_H
+
+#define IOPMP_EMMC      0
+#define IOPMP_SDIO0     1
+#define IOPMP_SDIO1     2
+#define IOPMP_USB0      3
+#define IOPMP_AO        4
+#define IOPMP_AUD       5
+#define IOPMP_CHIP_DBG  6
+#define IOPMP_EIP120I   7
+#define IOPMP_EIP120II  8
+#define IOPMP_EIP120III 9
+#define IOPMP_ISP0      10
+#define IOPMP_ISP1      11
+#define IOPMP_DSP       12
+#define IOPMP_DW200     13
+#define IOPMP_VENC      14
+#define IOPMP_VDEC      15
+#define IOPMP_G2D       16
+#define IOPMP_FCE       17
+#define IOPMP_NPU       18
+#define IOPMP0_DPU      19
+#define IOPMP1_DPU      20
+#define IOPMP_GPU       21
+#define IOPMP_GMAC1     22
+#define IOPMP_GMAC2     23
+#define IOPMP_DMAC      24
+#define IOPMP_TEE_DMAC  25
+
+typedef enum {
+	CSI_ATTR_R	= 1,
+	CSI_ATTR_W	= 2,
+} csi_iopmp_attr_t;
+
+/**
+ * @brief Light iopmp region permission setting.
+ *
+ * @param type
+ * @param attr
+ * @return csi_err_t
+ */
+int csi_iopmp_set_attr(int type, u_int8_t *start_addr, u_int8_t *end_addr, csi_iopmp_attr_t attr);
+
+/** iopmp lock
+ * @brief  Lock secure iopmp setting.
+ *
+ * @return csi_err_t
+ */
+int csi_iopmp_lock(void);
+
+#endif

BIN
light_fm_aon/light_aon_fpga.bin


BIN
light_fm_aon/light_aon_fpga.elf


+ 1 - 0
rambus_sec_lib/bin/EIP120_scripts/aad.txt

@@ -0,0 +1 @@
+feedfacedeadbeeffeedfacedeadbeefabaddad2

+ 186 - 0
rambus_sec_lib/bin/EIP120_scripts/ciphertest.sh

@@ -0,0 +1,186 @@
+#!/bin/bash
+
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+
+############################ constants ############################
+
+result=0
+ENGINE_ID_120=eip120
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+O1="cipherout1.txt" # Temporary file, used for cipher eip120 output
+O2="cipherout2.txt" # Temporary file, used for cipher 'internal' output
+#MES=testdatain.txt  #Data to encrypt or Decrypt
+MES=message.txt
+BIGMES=testdatain.txt
+IVFILE=iv.txt                            # IV file for test application
+KEYFILE=key.txt                          # Key file for test application
+TAGFILE=tag.txt                          # tag file for test application
+AADFILE=aad.txt                          # aad file for test application
+RED='\033[0;31m'
+GRN='\033[0;32m'
+NC='\033[0m' # No Color
+testarray=(aes-128-ecb aes-192-ecb aes-256-ecb
+           aes-128-cbc aes-192-cbc aes-256-cbc
+           aes-128-ctr aes-192-ctr aes-256-ctr
+           des-ecb des-cbc des-cfb des-ofb
+           des-ede3-ecb des-ede3-cbc des-ede3-cfb des-ede3-ofb
+           sm4-ecb sm4-cbc sm4-ctr)
+keysizearray=(16 24 32
+              16 24 32
+              16 24 32
+              8 8 8 8
+              24 24 24 24
+              16 16 16)
+ivsizearray=(0 0 0
+             16 16 16
+             16 16 16
+             0 8 8 8
+             0 8 8 8
+             0 16 16)
+testarrayxts=(aes-128-xts aes-256-xts)
+testarraygcm=(aes-128-gcm aes-192-gcm aes-256-gcm)
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+
+validate_environment()
+{
+    if [ ! -f $OPENSSL ]; then
+        echo "Error: openssl client not found"
+        exit 1
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        exit 1
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        exit 1
+    fi
+
+    ${OPENSSL} engine -t ${ENGINE_ID_120} &> /dev/null
+    if [ $? -ne 0 ]; then
+        echo -e "\n${RED}Error: OpenSSL engine ${ENGINE_ID_120} is not loaded${NC}"
+        exit 1
+    fi
+}
+
+check_diff()
+{
+    diff ${O1} ${O2} > /dev/null
+    if [ $? -ne 0 ]; then
+        echo -e "\n${RED}$1 $2 tests FAILED${NC}"
+        result=1
+        return
+    fi
+    if [ $2 = e ]; then
+        echo $1 ENCRYPTION PASSED
+    else
+        echo $1 DECRYPTION PASSED
+    fi
+}
+
+test_aes()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// test_aes $1 $2" >> ciphertest_$DATESTAMP.log
+    fi
+    $VALGRIND ./../build/cipher --type $1 --engine ${ENGINE_ID_120} --in ${BIGMES} --out ${O1} --op $2 --iv ${IVFILE} --key ${KEYFILE} > /dev/null
+    if [ $1 = aes-128-ecb ] || [ $1 = aes-192-ecb ] || [ $1 = aes-256-ecb ] ||
+       [ $1 = des-ecb ] || [ $1 = des-ede3-ecb ] || [ $1 = sm4-ecb ]; then
+    ${OPENSSL} $1 -nosalt -in ${BIGMES} -out ${O2} -$2 -K ${ckey:0:$3} -nopad > /dev/null
+    else
+    ${OPENSSL} $1 -nosalt -in ${BIGMES} -out ${O2} -$2 -K ${ckey:0:$3} -iv ${ivkey:0:$4} -nopad > /dev/null
+    fi
+    check_diff $1 $2
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> ciphertest_$DATESTAMP.log
+    fi
+}
+
+test_xts()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// test_xts $1 $2" >> ciphertest_$DATESTAMP.log
+    fi
+
+    $VALGRIND ./../build/cipher --type $1 --engine ${ENGINE_ID_120} --in ${MES} --out ${O1} --outdef ${O2} --op $2 --iv ${IVFILE} --key ${KEYFILE} > /dev/null
+    check_diff $1 $2
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> ciphertest_$DATESTAMP.log
+    fi
+}
+
+test_gcm()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// test_gcm $1 $2" >> ciphertest_$DATESTAMP.log
+    fi
+
+    if [ $2 = e ]; then
+        $VALGRIND ./../build/cipher --type $1 --engine ${ENGINE_ID_120} --in ${MES} --out ${O1} --outdef ${O2} --op $2 --iv ${IVFILE} --key ${KEYFILE} --tag ${TAGFILE} --aad ${AADFILE} > /dev/null
+        check_diff $1 $2
+    else
+        $VALGRIND ./../build/cipher --type $1 --engine ${ENGINE_ID_120} --in ${O1} --out ${O1} --outdef ${O2} --op $2 --iv ${IVFILE} --key ${KEYFILE} --tag ${TAGFILE} --aad ${AADFILE} > /dev/null
+        check_diff $1 $2
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> ciphertest_$DATESTAMP.log
+    fi
+}
+
+main () {
+    ${OPENSSL} version
+
+    validate_environment
+
+    if [ "$1" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK ciphertest valgrind results - $DATESTAMP" > ciphertest_$DATESTAMP.log
+    fi
+
+    ckey=$(<${KEYFILE})
+    ivkey=$(<${IVFILE})
+    for ((loop = 0; loop < ${#testarray[@]}; loop++)); do
+        test_aes ${testarray[loop]} e ${keysizearray[loop]}*2 ${ivsizearray[loop]}*2
+        test_aes ${testarray[loop]} d ${keysizearray[loop]}*2 ${ivsizearray[loop]}*2
+    done
+    for loop in ${testarraygcm[@]}; do
+        test_gcm $loop e
+        test_gcm $loop d
+    done
+    for loop in ${testarrayxts[@]}; do
+        test_xts $loop e
+        test_xts $loop d
+    done
+
+    rm ${O1} ${O2}
+    if [ ${result} -ne 0 ]; then
+        echo -e "\n${RED}Cipher tests FAILED${NC}"
+        return
+    fi
+    echo -e "\n${GRN}Cipher tests PASSED${NC}"
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+}
+
+main "$@"

+ 1 - 0
rambus_sec_lib/bin/EIP120_scripts/ckey.txt

@@ -0,0 +1 @@
+2b7e151628aed2a6abf7158809cf4f3c

+ 1 - 0
rambus_sec_lib/bin/EIP120_scripts/hkey.txt

@@ -0,0 +1 @@
+0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b

+ 219 - 0
rambus_sec_lib/bin/EIP120_scripts/htest.sh

@@ -0,0 +1,219 @@
+#!/bin/bash
+
+#*****************************************************************************
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+#*****************************************************************************
+
+############################ constants ############################
+
+result=0
+ENGINE_ID_120=eip120
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+O1="htest_tmp1.txt" # Temporary file, used for hash eip120 output
+O2="htest_tmp2.txt" # Temporary file, used for hash 'internal' output
+HKEY=hkey.txt       # HMAC key file
+CKEY=ckey.txt       # CMAC key file
+RED='\033[0;31m'
+GRN='\033[0;32m'
+NC='\033[0m' # No Color
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+
+validate_environment()
+{
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo -e "${RED}Error: openssl client not found${NC}"
+        exit 1
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo -e "${RED}Error: Environment variable OPENSSL_ENGINES is undefined${NC}"
+        exit 1
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo -e "${RED}Error: kernel module $KERNEL_MODULE not found${NC}"
+        exit 1
+    fi
+
+    ${OPENSSL} engine -t ${ENGINE_ID_120} &> /dev/null
+    if [ $? -ne 0 ]; then
+        echo -e "\n${RED}Error: OpenSSL engine ${ENGINE_ID_120} is not loaded${NC}"
+        exit 1
+    fi
+}
+
+check_diff()
+{
+    diff ${O1} ${O2} > /dev/null
+    if [ $? -ne 0 ]; then
+        echo $1 "(psize "$2")" FAILED
+        result=1
+        return
+    fi
+    echo $1 "(psize "$2")" PASSED
+}
+
+test_hmac()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// $1 $2" >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | $VALGRIND ${OPENSSL} dgst -engine ${ENGINE_ID_120} -$1 -out ${O1} -mac HMAC -macopt hexkey:$hkey &> /dev/null
+    if [ $? -ne 0 ]; then
+        echo "openssl with " $1 "(psize "$2")" FAILED
+        result=1
+        return
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | ${OPENSSL} dgst -$1 -out ${O2} -mac HMAC -macopt hexkey:$hkey > /dev/null
+    check_diff HMAC-$1 $2
+}
+
+test_hmacs()
+{
+    psizes=$2
+    for psize in ${psizes[@]}; do
+        test_hmac $1 $psize
+    done
+}
+
+test_cmac()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// $1 $2" >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | $VALGRIND ${OPENSSL} dgst -engine ${ENGINE_ID_120} -out ${O1} -mac CMAC -macopt cipher:$1 -macopt hexkey:$ckey &> /dev/null
+    if [ $? -ne 0 ]; then
+        echo "openssl with cipher " $1 "(psize "$2")" FAILED
+        result=1
+        return
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | ${OPENSSL} dgst -out ${O2} -mac CMAC -macopt cipher:$1 -macopt hexkey:$ckey > /dev/null
+    check_diff CMAC-$1 $2
+}
+
+test_cmacs()
+{
+    psizes=$2
+    for psize in ${psizes[@]}; do
+        test_cmac $1 $psize
+    done
+}
+
+test_hash()
+{
+    if [ $DO_VALGRIND ]; then
+        echo "// $1 $2" >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | $VALGRIND ${OPENSSL} dgst -out ${O1} -$1 -engine eip120 -engine_impl &> /dev/null
+    if [ $? -ne 0 ]; then
+        echo "openssl with" $1 "(psize "$2")" FAILED
+        result=1
+        return
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> htest_$DATESTAMP.log
+    fi
+
+    head -c $2 lorum.txt | ${OPENSSL} dgst -out ${O2} -$1 &> /dev/null
+    check_diff HASH-$1 $2
+}
+
+test_hashes()
+{
+    psizes=$2
+    for psize in ${psizes[@]}; do
+        test_hash $1 $psize
+    done
+}
+
+main () {
+    ${OPENSSL} version
+
+    validate_environment
+
+    if [ "$1" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK eip120 hash valgrind results - $DATESTAMP" > htest_$DATESTAMP.log
+    fi
+
+    hkey=$(<${HKEY})
+    test_hmacs sha1 '0 3 56 64 128 192 256 320 1023'
+    test_hmacs sha224 '0 3 56 64 128 192 256 320 1023'
+    test_hmacs sha256 '0 3 56 64 128 192 256 320 1023'
+    test_hmacs sha384 '0 3 56 128 256 384 512 640 1023'
+    test_hmacs sha512 '0 3 56 128 256 384 512 640 1023'
+    test_hmacs sha3-224 '0 3 56 144 288 432 576 720 1023'
+    test_hmacs sha3-256 '0 3 56 136 272 408 544 680 1023'
+    test_hmacs sha3-384 '0 3 56 104 208 312 416 520 1023'
+    test_hmacs sha3-512 '0 3 56 72 144 216 288 360 1023'
+    test_hmacs sm3 '0 3 56 64 128 256 384 512 640 1023'
+
+    ckey=$(<${CKEY})
+    test_cmacs aes-128-ecb '0 16 32 48 64 80 1023'
+    test_cmacs sm4-ecb '0 16 32 48 64 80 1023'
+
+    test_hashes sha1 '128 192 256 320 1023'
+    test_hashes sha224 '128 192 256 320 1023'
+    test_hashes sha256 '128 192 256 320 1023'
+    test_hashes sha384 '256 384 512 640 1023'
+    test_hashes sha512 '256 384 512 640 1023'
+    test_hashes sha3-224 '288 432 576 720 1023'
+    test_hashes sha3-256 '272 408 544 680 1023'
+    test_hashes sha3-384 '208 312 416 520 1023'
+    test_hashes sha3-512 '144 216 288 360 1023'
+    test_hashes sm3 '128 256 384 512 640 1023'
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    unset DO_VALGRIND
+    unset VALGRIND
+
+    test_hashes sha1 '3 56 64'
+    test_hashes sha224 '3 56 64'
+    test_hashes sha256 '3 56 64'
+    test_hashes sha384 '3 56 128'
+    test_hashes sha512 '3 56 128'
+    test_hashes sha3-224 '3 56 144'
+    test_hashes sha3-256 '3 56 136'
+    test_hashes sha3-384 '3 56 104'
+    test_hashes sha3-512 '3 56 72'
+    test_hashes sm3 '3 56 64'
+
+    rm ${O1} ${O2}
+    if [ ${result} -ne 0 ]; then
+        echo -e "\n${RED}Hash tests FAILED${NC}"
+        return
+    fi
+    echo -e "\n${GRN}Hash tests PASSED${NC}"
+}
+
+main "$@"

+ 1 - 0
rambus_sec_lib/bin/EIP120_scripts/iv.txt

@@ -0,0 +1 @@
+12345678901234567890123456789012

+ 1 - 0
rambus_sec_lib/bin/EIP120_scripts/key.txt

@@ -0,0 +1 @@
+feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308

File diff suppressed because it is too large
+ 0 - 0
rambus_sec_lib/bin/EIP120_scripts/lorum.txt


File diff suppressed because it is too large
+ 0 - 0
rambus_sec_lib/bin/EIP120_scripts/message.txt


+ 0 - 0
rambus_sec_lib/bin/EIP120_scripts/tag.txt


File diff suppressed because it is too large
+ 0 - 0
rambus_sec_lib/bin/EIP120_scripts/testdatain.txt


+ 344 - 0
rambus_sec_lib/bin/EIP28_scripts/dh-key-agreement.sh

@@ -0,0 +1,344 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+# 
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+#
+# Tests:
+#     1. DH key exchange, matching private key public peer key  (openssl, openssl)
+#     2. DH key exchange, matching private key public peer key  (engine, engine)
+#
+# Setup:
+# 1. Configure the openssl:   export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:         export OPENSSL_ENGINES=/path/to/engines
+#
+# Usage:
+#    run all tests:   bash dh-key-agreement.sh
+#     run a test:     bash dh-key-agreement.sh <test number>
+#
+# Date:        12/8/2021 
+##############################################################################
+
+############################ constants ############################
+PASS=0
+FAIL=1
+DEBUG=false
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+is_engine_available() {
+    if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
+        echo "Error: engine unavailable"
+        return $FAIL
+    fi
+    return $PASS
+}    
+
+print_configuration() {
+    echo "DEBUG           $DEBUG         "
+    echo "VALIDATE_SETUP  $VALIDATE_SETUP"
+    echo "ENGINE_ID_28    $ENGINE_ID_28  "
+    echo "KERNEL_MODULE   $KERNEL_MODULE "
+    echo "OPENSSL         $OPENSSL       "
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_dh_key_params() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local dh_key_params_file=$2
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # create key params:
+    # openssl genpkey -genparam -algorithm DH -out dhp.pem
+    # examine key params:
+    # openssl pkeyparam -in dhp.pem -text
+    print=`${OPENSSL} genpkey \
+        -genparam \
+        $parameter_engine \
+        -algorithm DH \
+        -out $dh_key_params_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    return $ret
+}
+
+create_dh_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local dh_key_params_file=$2
+    local private_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate private DH key:
+    # openssl genpkey -paramfile dhp.pem -out dhkey1.pem
+    # examine private key:
+    # openssl pkey -in dhkey2.pem -text -noout
+    print=`${OPENSSL} genpkey \
+        $parameter_engine \
+        -paramfile $dh_key_params_file \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+    return $ret
+}
+
+derive_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate public key:
+    # openssl pkey -in dhkey1.pem -pubout -out dhpub1.pem
+    # examine public key:
+    # openssl pkey -pubin -in dhpub1.pem -text
+    print=`${OPENSSL} pkey \
+        $parameter_engine \
+        -in $private_key_file \
+        -pubout \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+    return $ret
+}
+
+derive_shared_secret() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_peer_file=$3
+    local output_secert_file=$4
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// derive_shared_secret $2 $3 $4" >> dh-key-agreement_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    # openssl pkeyutl -derive -inkey alice.pem -peerkey bob.pub -out alicebob.key
+    print=`$valgrind $OPENSSL pkeyutl \
+        -derive \
+        $parameter_engine \
+        -inkey $private_key_file \
+        -peerkey $public_key_peer_file \
+        -out $output_secert_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> dh-key-agreement_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_dh_key_exchange_positive() {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    cleanup key_params.pem private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_dh_key_params false key_params.pem
+    [ $? -ne 0 ] && return 1
+    create_dh_private_key false key_params.pem private1.pem
+    [ $? -ne 0 ] && return 2
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 3
+    create_dh_private_key false key_params.pem private2.pem
+    [ $? -ne 0 ] && return 4
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 5
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 6
+    derive_shared_secret $use_engine_2 private2.pem public1.pem secret2.bin
+    [ $? -ne 0 ] && return 7
+    cmp -s secret1.bin secret2.bin
+    [ $? -ne 0 ] && return 8
+    return $PASS
+}
+
+test_dh_key_exchange_negative() {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_EC_private_key false P-256 private1.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 2
+    create_EC_private_key false P-256 private2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 4
+    create_EC_private_key false P-256 private3.pem
+    [ $? -ne 0 ] && return 5
+    derive_public_key false private3.pem public3.pem
+    [ $? -ne 0 ] && return 6
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 7
+    derive_shared_secret $use_engine_2 private2.pem public3.pem secret2.bin
+    [ $? -ne 0 ] && return 8
+    cmp -s secret1.bin secret2.bin
+    [ $? -eq 0 ] && return 6
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    echo "Test: DH key agreement"
+    # arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null; then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    # validation
+    if [ $VALIDATE_SETUP == true ]; then
+        echo "validate setup"
+        validate_environment
+        [ $? -eq $FAIL ] && exit 1
+        is_engine_available
+        [ $? -eq $FAIL ] && exit 1
+        print_configuration
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK dh-key-agreement valgrind results - $DATESTAMP" > dh-key-agreement_$DATESTAMP.log
+    fi
+
+    # tests:
+    tests_run=0
+    tests_pass=0
+    tests_total=3
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="DH key exchange, matching private key public peer key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_dh_key_exchange_positive false false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="DH key exchange, matching private key public peer key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_dh_key_exchange_positive true true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="DH key exchange, matching private key public peer key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_dh_key_exchange_positive false true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    echo "tests: $tests_total run: $tests_run passed: $tests_pass"
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    exit 0
+}
+
+main "$@"

+ 342 - 0
rambus_sec_lib/bin/EIP28_scripts/ecdh-key-agreement.sh

@@ -0,0 +1,342 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+#
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+#
+# Tests: 
+#     1. ECDH key exchange, curve P-256, matching private key public peer key (openssl, openssl)
+#     2. ECDH key exchange, curve P-256, matching private key public peer key P-256 (engine, engine)
+#     3. ECDH key exchange, curve P-256, matching private key public peer key P-256 (openssl, engine)
+#     4. ECDH key exchange, curve P-256, unmatching private key public peer key P-256 (openssl, openssl)
+#     5. ECDH key exchange, curve P-256, unmatching private key public peer key P-256 (openssl, engine)
+#
+# Setup:
+# 1. Configure the openssl:   export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:         export OPENSSL_ENGINES=/path/to/engines
+#
+# Usage:
+#    run all tests:    bash ecdh-key-agreement.sh
+#     run a test:        bash ecdh-key-agreement.sh <test number>
+#
+# Date:        12/8/2021
+##############################################################################
+
+############################ constants ############################
+PASS=0
+FAIL=1
+DEBUG=false
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+is_engine_available() {
+    if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
+        echo "Error: engine unavailable"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_configuration() {
+    echo "DEBUG           $DEBUG         "
+    echo "VALIDATE_SETUP  $VALIDATE_SETUP"
+    echo "ENGINE_ID_28    $ENGINE_ID_28  "
+    echo "KERNEL_MODULE   $KERNEL_MODULE "
+    echo "OPENSSL         $OPENSSL       "
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_EC_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local curve=$2
+    local private_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate private key:
+    # openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out private.pem
+    # examine private key:
+    # openssl ec -in private.pem -noout -text
+    print=`${OPENSSL} genpkey \
+        $parameter_engine \
+        -algorithm EC \
+        -pkeyopt ec_paramgen_curve:$curve \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+    return $ret
+}
+
+derive_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate public key:
+    # openssl ec -pubout -in private.pem -out public.pem
+    # examine public key:
+    # openssl pkey -noout -text -inform PEM -in public.pem -pubin
+    print=`${OPENSSL} pkey \
+        $parameter_engine \
+        -pubout \
+        -in $private_key_file \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+    return $ret
+}
+
+derive_shared_secret() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_peer_file=$3
+    local output_secert_file=$4
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// derive_shared_secret $2 $3 $4" >> ecdh-key-agreement_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    # openssl pkeyutl -derive -inkey alice.pem -peerkey bob.pub -out alicebob.key
+    print=`$valgrind $OPENSSL pkeyutl \
+        -derive \
+        $parameter_engine \
+        -inkey $private_key_file \
+        -peerkey $public_key_peer_file \
+        -out $output_secert_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> ecdh-key-agreement_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_ecdh_key_exchange_positive() {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    local curve=$3
+    cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_EC_private_key false $curve private1.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 2
+    create_EC_private_key false $curve private2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 4
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 5
+    derive_shared_secret $use_engine_2 private2.pem public1.pem secret2.bin
+    [ $? -ne 0 ] && return 5
+    cmp -s secret1.bin secret2.bin
+    [ $? -ne 0 ] && return 5
+    return $PASS
+}
+
+test_ecdh_key_exchange_negative() {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    local curve=$3
+    cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_EC_private_key false $curve private1.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 2
+    create_EC_private_key false $curve private2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 4
+    create_EC_private_key false $curve private3.pem
+    [ $? -ne 0 ] && return 5
+    derive_public_key false private3.pem public3.pem
+    [ $? -ne 0 ] && return 6
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 7
+    derive_shared_secret $use_engine_2 private2.pem public3.pem secret2.bin
+    [ $? -ne 0 ] && return 8
+    cmp -s secret1.bin secret2.bin
+    [ $? -eq 0 ] && return 6
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    echo "Test: ECDH key agreement"
+    # arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null; then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    # validation
+    if [ $VALIDATE_SETUP == true ]; then
+        echo "validate setup"
+        validate_environment
+        [ $? -eq $FAIL ] && exit 1
+        is_engine_available
+        [ $? -eq $FAIL ] && exit 1
+        print_configuration
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK ecdh-key-agreement valgrind results - $DATESTAMP" > ecdh-key-agreement_$DATESTAMP.log
+    fi
+
+    # tests:
+    tests_run=0
+    tests_pass=0
+    tests_total=5
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="ECDH key exchange, curve P-256, matching private key public peer key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_ecdh_key_exchange_positive false false P-256
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="ECDH key exchange, curve P-256, matching private key public peer key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_ecdh_key_exchange_positive true true P-256
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="ECDH key exchange, curve P-256, matching private key public peer key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_ecdh_key_exchange_positive false true P-256
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 4 ]; then
+        test_name="ECDH key exchange, curve P-256, unmatching private key public peer key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_ecdh_key_exchange_negative false false P-256
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 5 ]; then
+        test_name="ECDH key exchange, curve P-256, unmatching private key public peer key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_ecdh_key_exchange_negative false true P-256
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    echo "tests: $tests_total run: $tests_run passed: $tests_pass"
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    exit 0
+}
+
+main "$@"

+ 380 - 0
rambus_sec_lib/bin/EIP28_scripts/edcsa-sign-and-verify.sh

@@ -0,0 +1,380 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+#
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+# Tests:
+#     1. ECDSA sign and verify openssl positive flow
+#     2. ECDSA sign and verify engine eip28 positive flow
+#     3. ECDSA sign and verify openssl negative flow
+#     4. ECDSA sign and verify engine eip28 negative flow
+# Setup:
+# Setup:
+# 1. Configure the openssl:        export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:            export OPENSSL_ENGINES=/path/to/engines
+# Usage:
+#    run all tests:        bash sign-and-verify.sh
+#     run specific test:    bash sign-and-verify.sh <test number>
+#
+# Date:        12/8/2021 
+##############################################################################
+
+############################ constants ############################
+
+DEBUG=false
+OPENSSL=$OPENSSL_DIR/apps/openssl
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+PASS=0
+FAIL=1
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    which openssl
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_ECDSA_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// create_ECDSA_private_key $2" >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    # possible curves: ${OPENSSL} ecparam -list_curves
+    # prev. curve tested: secp384r1
+    local ret
+    local print
+    print=`$valgrind ${OPENSSL} ecparam \
+        $parameter_engine \
+        -genkey \
+        -name secp224r1 \
+        -noout \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+create_ECDSA_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// create_ECDSA_public_key $2 $3" >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    print=`$valgrind ${OPENSSL} ec \
+        $parameter_engine \
+        -pubout \
+        -in $private_key_file \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+hash_the_file() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local hash=$2
+    local message_file=$3
+    local hash_file=$4
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// hash_the_file $2 $3 $4" >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    print=`$valgrind ${OPENSSL} dgst \
+        $parameter_engine \
+        -sha256 \
+        -out $hash_file \
+        -binary \
+        ${message_file} 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && hexdump -x $hash_file
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+sign_the_hash() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local hash=$2
+    local private_key_file=$3
+    local hash_file=$4
+    local signature_file=$5
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// sign_the_hash $2 $3 $4 $5" >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    print=`$valgrind ${OPENSSL} pkeyutl \
+        $parameter_engine \
+        -sign \
+        -out ${signature_file} \
+        -in ${hash_file} \
+        -inkey ${private_key_file} \
+        -keyform pem \
+        -pkeyopt digest:sha256 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && hexdump -x $signature_file
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+validate_the_hash_with_the_signature() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local public_key_file=$2
+    local signature_file=$3
+    local hash_file=$4
+    local ret
+    local print
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// validate_the_hash_with_the_signature $2 $3 $4 $5" >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    print=`$valgrind ${OPENSSL} pkeyutl \
+        -verify \
+        $parameter_engine \
+        -pubin \
+        -inkey ${public_key_file} \
+        -in ${hash_file} \
+        -sigfile ${signature_file} \
+        -keyform pem \
+        -pkeyopt digest:sha256 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_ecdsa_sign_and_verify_positive() {
+    local use_engine=$1
+    cleanup test.file ec_private.pem ec_public.pem ec_signature.bin test.file.hash
+    create_test_file test.file 50
+    create_ECDSA_private_key $use_engine ec_private.pem
+    [ $? -ne 0 ] && return $FAIL
+    hash_the_file $use_engine sha256 test.file test.file.hash
+    [ $? -ne 0 ] && return $FAIL
+    sign_the_hash $use_engine sha256 ec_private.pem test.file.hash ec_signature.bin
+    [ $? -ne 0 ] && return $FAIL
+    create_ECDSA_public_key $use_engine ec_private.pem ec_public.pem
+    [ $? -ne 0 ] && return $FAIL
+    validate_the_hash_with_the_signature $use_engine ec_public.pem ec_signature.bin test.file.hash
+    [ $? -ne 0 ] && return $FAIL
+    return $PASS
+}
+
+test_ecdsa_sign_and_verify_negative() {
+    local use_engine=$1
+    cleanup test.file ec_private.pem ec_private_2.pem ec_public_2.pem ec_signature.bin test.file.hash
+    create_test_file test.file 50
+    create_ECDSA_private_key $use_engine ec_private.pem
+    [ $? -ne 0 ] && return $FAIL
+    hash_the_file $use_engine sha256 test.file test.file.hash
+    [ $? -ne 0 ] && return $FAIL
+    sign_the_hash $use_engine sha256 ec_private.pem test.file.hash ec_signature.bin
+    [ $? -ne 0 ] && return $FAIL
+    create_ECDSA_private_key $use_engine ec_private_2.pem
+    [ $? -ne 0 ] && return $FAIL
+    create_ECDSA_public_key $use_engine ec_private_2.pem ec_public_2.pem
+    [ $? -ne 0 ] && return $FAIL
+    validate_the_hash_with_the_signature $use_engine ec_public_2.pem ec_signature.bin test.file.hash
+    [ $? -eq 0 ] && return $FAIL # THIS IS A NEGATIVE TEST
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    # script arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null;  then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    if [ $VALIDATE_SETUP == true ]; then
+        validate_environment
+        [ $? -eq 1 ] && exit 1
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK edcsa-sign-and-verify valgrind results - $DATESTAMP" > edcsa-sign-and-verify_$DATESTAMP.log
+    fi
+
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="ECDSA sign and verify using a matching pub key (openssl)"
+        printf "Test %s: " "$test_name"
+        test_ecdsa_sign_and_verify_positive false
+        [ $? -eq $PASS ] && echo "PASSED" || echo "FAILED"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="ECDSA sign and verify using a matching pub key"
+        printf "Test %s: " "$test_name"
+        test_ecdsa_sign_and_verify_positive true
+        [ $? -eq $PASS ] && echo "PASSED" || echo "FAILED"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="ECDSA sign and verify using an unmatching pub key (openssl)"
+        printf "Test %s: " "$test_name"
+        test_ecdsa_sign_and_verify_negative false
+        [ $? -eq $PASS ] && echo "PASSED" || echo "FAILED"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 4 ]; then
+        test_name="ECDSA sign and verify using an unmatching pub key (eip28)"
+        printf "Test %s: " "$test_name"
+        test_ecdsa_sign_and_verify_negative true
+        [ $? -eq $PASS ] && echo "PASSED" || echo "FAILED"
+    fi
+
+   if [ $DO_VALGRIND ]; then
+       rm $TEMPFILE
+   fi
+
+    exit 0
+}
+
+main "$@"

+ 415 - 0
rambus_sec_lib/bin/EIP28_scripts/rsa-encrypt-decrypt-sign-verify.sh

@@ -0,0 +1,415 @@
+#!/bin/bash
+
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+
+############################ constants ############################
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+# configure based engine id
+engine_id=eip28pka
+
+############################ functions ############################
+
+if [ -z "${OPENSSL_DIR}" ]; then
+    echo "Error: OPENSSL_DIR not set."
+    echo "Please let an environment named OPENSSL_DIR refer to the"
+    echo "directory where the OpenSSL package was built, such that"
+    echo "\${OPENSSL_DIR}/apps/openssl refers to the openssl app to use."
+    exit 1
+fi
+
+# Run various test with the following instance of OpenSSL.
+OSSL=${OPENSSL_DIR}/apps/openssl
+if [ ! -x ${OSSL} ]; then
+    echo "Error: ${OSSL} not found or not executable?!"
+    exit 1
+fi
+
+# Pad `file` such that its size equals `target_size`.
+padd_file () {
+    local file=$1
+    local target_size=$2
+    local padding="++++++++"
+    local text=$(cat ${file})
+
+    while (( ${#padding} < ${target_size} )); do
+        padding="${padding}${padding}"
+    done
+    echo "${padding}${text}" | tail --bytes ${target_size} - > ${file}
+}
+
+# Generate an RSA keypair of the specified size and store
+# it in the specified .pem file.
+ossl_gen_rsa_key () {
+    local nbits=$1
+    local keyfile=$2
+    local keyform=${keyfile##*.}
+
+    if [[ "${keyform}" != "pem" ]]; then
+        echo "ossl_gen_rsa_key: filename must end with .pem"
+    else
+        ${OSSL} genpkey -out ${keyfile} -outform ${keyform} \
+                -algorithm RSA -pkeyopt rsa_keygen_bits:${nbits}
+    fi
+}
+
+# Show the RSA keypair stored in the specified .pem or .der file.
+ossl_show_rsa_key () {
+    local keyfile=$1
+    local keyform=${keyfile##*.}
+
+    if [[ "${keyform}" != "pem" && "${keyform}" != "der" ]]; then
+        echo "ossl_show_key: filename must end with .der or .pem"
+    else
+        if [[ "${keyform}" == "pem" ]]; then
+            # Convert .pem to .der
+            ${OSSL} rsa -out __@der@__ -outform der -in ${keyfile}
+            ${OSSL} asn1parse -in __@der@__ -inform der
+            rm -f __@der@__
+        else
+            ${OSSL} asn1parse -in ${keyfile} -inform ${keyform}
+        fi
+    fi
+}
+
+# Use the indicated RSA scheme (pkcs1 or pss) to sign the given
+# `msgfile`, with the (private) RSA key coming from `keyfile` and
+# store the signature in `sigfile`.
+# For the moment, the hash algorithm used is always SHA256.
+ossl_rsa_sign () {
+    local msgfile=$1
+    local keyfile=$2
+    local sigfile=$3
+    local padding=$4 # pkcs1 or pss
+    local keyform=${keyfile##*.}
+    local opt_saltlen=""
+    local hashalg="sha256"
+
+    if [[ "${padding}" == "pss" ]]; then
+        opt_saltlen="-pkeyopt rsa_pss_saltlen:32"
+    fi
+
+    ${OSSL} dgst -${hashalg} -out __@hash@__ -binary ${msgfile}
+    ${OSSL} pkeyutl -sign -out ${sigfile} -in __@hash@__ \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} \
+            -pkeyopt digest:${hashalg} ${opt_saltlen}
+    rm -f __@hash@__
+}
+
+# Use the indicated RSA scheme (pkcs1 or pss) to verify if the
+# signature in `sigfile` matches the given `msgfile`, with the
+# (public) RSA key coming from `keyfile`.
+# For the moment, the hash algorithm used is always SHA256.
+ossl_rsa_vrfy() {
+    local msgfile=$1
+    local keyfile=$2
+    local sigfile=$3
+    local verfile=$4
+    local padding=$5
+    local keyform=${keyfile##*.}
+    local opt_saltlen=""
+    local hashalg="sha256"
+
+    if [[ "${padding}" == "pss" ]]; then
+        opt_saltlen="-pkeyopt rsa_pss_saltlen:32"
+    fi
+
+    ${OSSL} dgst -${hashalg} -out __@hash@__ -binary ${msgfile}
+    ${OSSL} pkeyutl -verify -in __@hash@__ -sigfile ${sigfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} \
+            -pkeyopt digest:${hashalg} ${opt_saltlen} \
+            -out ${verfile}
+    rm -f __@hash@__
+}
+
+# Use the indicated RSA scheme (pkcs1 or pss) to sign the given
+# `msgfile`, with the (private) RSA key coming from `keyfile` and
+# store the signature in `sigfile`.
+# For the moment, the hash algorithm used is always SHA256.
+ossl_engine_rsa_sign () {
+    local msgfile=$1
+    local keyfile=$2
+    local sigfile=$3
+    local padding=$4 # pkcs1 or pss
+    local keyform=${keyfile##*.}
+    local opt_saltlen=""
+    local hashalg="sha256"
+
+    if [[ "${padding}" == "pss" ]]; then
+        opt_saltlen="-pkeyopt rsa_pss_saltlen:32"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        echo "// ossl_engine_rsa_sign $2 $3 $4" >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    ${OSSL} dgst -${hashalg} -out __@hash@__ -binary ${msgfile}
+    $VALGRIND ${OSSL} pkeyutl -engine ${engine_id} -sign -out ${sigfile} -in __@hash@__ \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} \
+            -pkeyopt digest:${hashalg} ${opt_saltlen}
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    rm -f __@hash@__
+}
+
+# Use the indicated RSA scheme (pkcs1 or pss) to verify if the
+# signature in `sigfile` matches the given `msgfile`, with the
+# (public) RSA key coming from `keyfile`.
+# For the moment, the hash algorithm used is always SHA256.
+ossl_engine_rsa_vrfy() {
+    local msgfile=$1
+    local keyfile=$2
+    local sigfile=$3
+    local verfile=$4
+    local padding=$5
+    local keyform=${keyfile##*.}
+    local opt_saltlen=""
+    local hashalg="sha256"
+
+    if [[ "${padding}" == "pss" ]]; then
+        opt_saltlen="-pkeyopt rsa_pss_saltlen:32"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        echo "// ossl_engine_rsa_vrfy $2 $3 $4 $5" >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    ${OSSL} dgst -${hashalg} -out __@hash@__ -binary ${msgfile}
+    $VALGRIND ${OSSL} pkeyutl -engine ${engine_id} -verify -in __@hash@__ -sigfile ${sigfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} \
+            -pkeyopt digest:${hashalg} ${opt_saltlen} \
+            -out ${verfile}
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    rm -f __@hash@__
+}
+
+# Use the indicated RSA scheme (none, pkcs1 or oaep) to encrypt the given
+# `ptxfile`, with the (public) RSA key coming from `keyfile` and
+# store the cryptogram in `ctxfile`.
+ossl_rsa_encrypt () {
+    local ptxfile=$1
+    local keyfile=$2
+    local ctxfile=$3
+    local padding=$4 # none, pkcs1 or oaep
+    local hashalg="sha1"
+    local keyform=${keyfile##*.}
+    local opt_mgf1_md=""
+    local opt_digest=""
+
+    if [[ "${padding}" == "oaep" ]]; then
+        :
+        # opt_mgf1_md="-pkeyopt rsa_mgf1_md:${hashalg}"
+        # opt_digest="-pkeyopt digest:${hashalg}"
+    fi
+
+    ${OSSL} pkeyutl -encrypt -out ${ctxfile} -in ${ptxfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} ${opt_mgf1_md} ${opt_digest}
+}
+
+# Use the indicated RSA scheme (none, pkcs1 or oaep) to encrypt the given
+# `ptxfile`, with the (public) RSA key coming from `keyfile` and
+# store the cryptogram in `ctxfile`.
+ossl_engine_rsa_encrypt () {
+    local ptxfile=$1
+    local keyfile=$2
+    local ctxfile=$3
+    local padding=$4 # none, pkcs1 or oaep
+    local hashalg="sha1"
+    local keyform=${keyfile##*.}
+    local opt_mgf1_md=""
+    local opt_digest=""
+
+    if [[ "${padding}" == "oaep" ]]; then
+        :
+        # opt_mgf1_md="-pkeyopt rsa_mgf1_md:${hashalg}"
+        # opt_digest="-pkeyopt digest:${hashalg}"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        echo "// ossl_engine_rsa_encrypt $2 $3 $4" >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    $VALGRIND ${OSSL} pkeyutl -engine ${engine_id} -encrypt -out ${ctxfile} -in ${ptxfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} ${opt_mgf1_md} ${opt_digest}
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+}
+
+# Use the indicated RSA scheme (none, pkcs1 or oaep) to decrypt the given
+# `ctxfile`, with the (private) RSA key coming from `keyfile` and
+# store the plain text in `msgfile`.
+ossl_rsa_decrypt () {
+    local ctxfile=$1
+    local keyfile=$2
+    local msgfile=$3
+    local padding=$4 # none, pkcs1 or oaep
+    local hashalg="sha1"
+    local keyform=${keyfile##*.}
+    local opt_mgf1_md=""
+    local opt_digest=""
+
+    if [[ "${padding}" == "oaep" ]]; then
+        :
+        # opt_mgf1_md="-pkeyopt rsa_mgf1_md:${hashalg}"
+        # opt_digest="-pkeyopt digest:${hashalg}"
+    fi
+
+    ${OSSL} pkeyutl -decrypt -out ${msgfile} -in ${ctxfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} ${opt_mgf1_md} ${opt_digest}
+}
+
+# Use the indicated RSA scheme (none, pkcs1 or oaep) to decrypt the given
+# `ctxfile`, with the (private) RSA key coming from `keyfile` and
+# store the plain text in `msgfile`.
+ossl_engine_rsa_decrypt () {
+    local ctxfile=$1
+    local keyfile=$2
+    local msgfile=$3
+    local padding=$4 # none, pkcs1 or oaep
+    local hashalg="sha1"
+    local keyform=${keyfile##*.}
+    local opt_mgf1_md=""
+    local opt_digest=""
+
+    if [[ "${padding}" == "oaep" ]]; then
+        :
+        # opt_mgf1_md="-pkeyopt rsa_mgf1_md:${hashalg}"
+        # opt_digest="-pkeyopt digest:${hashalg}"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        echo "// ossl_engine_rsa_decrypt $2 $3 $4" >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    $VALGRIND ${OSSL} pkeyutl -engine ${engine_id} -decrypt -out ${msgfile} -in ${ctxfile} \
+            -inkey ${keyfile} -keyform ${keyform} \
+            -pkeyopt rsa_padding_mode:${padding} ${opt_mgf1_md} ${opt_digest}
+
+    if [ $DO_VALGRIND ]; then
+        cat $TEMPFILE >> rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+}
+
+# Perform an RSA sign-and-verify test with the specified
+# RSA key size and padding/scheme (i.e. pkcs1 or pss).
+rsa_sign_and_vrfy_test() {
+    local nbits=$1
+    local padding=$2
+    local keyfile="rsakey_${nbits}.pem"
+    local msgfile="message.txt"
+    local sigfile="signature_${padding}_${nbits}"
+    local verfile="verify_${padding}_${nbits}"
+    local res="FAILED"
+
+    # ossl_gen_rsa_key ${nbits} ${keyfile}
+    # ossl_show_rsa_key ${keyfile}
+    echo "My message to sign." > ${msgfile}
+    # test engine sign
+    ossl_engine_rsa_sign ${msgfile} ${keyfile} ${sigfile} ${padding}
+    ossl_rsa_vrfy ${msgfile} ${keyfile} ${sigfile} ${verfile} ${padding}
+    if grep -q 'Successfully' ${verfile}; then
+        res="PASSED"
+    else
+        res="FAILED"
+    fi
+    echo "[INFO] ${engine_id} rsa_sign_test (${nbits}, ${padding}):${res}"
+    # test engine verify
+    ossl_rsa_sign ${msgfile} ${keyfile} ${sigfile} ${padding}
+    ossl_engine_rsa_vrfy ${msgfile} ${keyfile} ${sigfile} ${verfile} ${padding}
+    if grep -q 'Successfully' ${verfile}; then
+        res="PASSED"
+    else
+        res="FAILED"
+    fi
+    echo "[INFO] ${engine_id} rsa_verify_test (${nbits}, ${padding}):${res}"
+}
+
+# Perform an RSA encrypt-and-decrypt test with the specified
+# RSA key size and padding/scheme (i.e. none, pkcs1 or oaep).
+rsa_encrypt_and_decrypt_test() {
+    local nbits=$1
+    local padding=$2
+    local keyfile="rsakey_${nbits}.pem"
+    local ptxfile="plaintxt"
+    local ctxfile="ciphertxt_${padding}_${nbits}"
+    local outfile="plain.out"
+    local res="FAILED"
+
+    echo "My message to encrypt." > ${ptxfile}
+    if [[ "${padding}" == "none" ]]; then
+        # Apparently, with padding set to `none`,
+        # the size of the input must equal the modulus size?!
+        cp ${ptxfile} ${ptxfile}_${nbits}_none
+        ptxfile=${ptxfile}_${nbits}_none
+        padd_file ${ptxfile} $(( ${nbits} / 8 ))
+    fi
+    ossl_engine_rsa_encrypt ${ptxfile} ${keyfile} ${ctxfile} ${padding}
+    ossl_rsa_decrypt ${ctxfile} ${keyfile} ${outfile} ${padding}
+    /usr/bin/diff --brief ${ptxfile} ${outfile} && res="PASSED"
+    echo "[INFO] ${engine_id} rsa_encrypt_test (${nbits}, ${padding}): ${res}"
+
+    res="FAILED"
+    ossl_rsa_encrypt ${ptxfile} ${keyfile} ${ctxfile} ${padding}
+    ossl_engine_rsa_decrypt ${ctxfile} ${keyfile} ${outfile} ${padding}
+    /usr/bin/diff --brief ${ptxfile} ${outfile} && res="PASSED"
+    echo "[INFO] ${engine_id} rsa_decrypt_test (${nbits}, ${padding}): ${res}"
+}
+
+main () {
+    ${OSSL} version
+
+
+    if [ "$1" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK rsa-encrypt-decrypt-sign-verify valgrind results - $DATESTAMP" > rsa-encrypt-decrypt-sign-verify_$DATESTAMP.log
+    fi
+
+    echo "**************************"
+    echo "Generate RSA Keys"
+    ossl_gen_rsa_key 2048 rsakey_2048.pem
+    ossl_gen_rsa_key 3072 rsakey_3072.pem
+    echo "**************************"
+    echo "Test RSA Sign & Verify"
+    rsa_sign_and_vrfy_test 2048 pkcs1
+    rsa_sign_and_vrfy_test 3072 pss
+    echo "**************************"
+    echo "Test RSA Encrypt & Decrypt"
+    rsa_encrypt_and_decrypt_test 3072 none
+    rsa_encrypt_and_decrypt_test 2048 pkcs1
+    rsa_encrypt_and_decrypt_test 2048 oaep
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+}
+
+main "$@"

+ 376 - 0
rambus_sec_lib/bin/EIP28_scripts/sm2-encrypt-and-decrypt.sh

@@ -0,0 +1,376 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+#
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+#
+# Tests:
+#     1. SM2 encrypt (openssl) and decrypt (openssl) / matching private and public key
+#     2. SM2 sign (engine) and verify (engine) / matching private and public key
+#     3. SM2 sign (engine) and verify (openssl) / matching private and public key
+#     4. SM2 sign (openssl) and verify (engine) / matching private and public key
+#     5. SM2 sign (openssl) and verify (openssl) / unmatching private and public key
+#     6. SM2 sign (engine) and verify (engine) / unmatching private and public key
+#
+# Setup:
+# 1. Configure the openssl:        export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:            export OPENSSL_ENGINES=/path/to/engines
+# 3. Configure the SM2 tool:    export SM2TOOL_DIR="/path/to/sm2"
+#
+# Usage:
+#    run all tests:    bash sm2-encrypt-and-decrypt.sh
+#     run a test:        bash sm2-encrypt-and-decrypt.sh <test number>
+#
+# Date:        12/8/2021 
+##############################################################################
+
+############################ constants ############################
+PASS=0
+FAIL=1
+DEBUG=false
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+SM2ENCRYPT=$SM2TOOL_DIR/sm2encrypt
+SM2DECRYPT=$SM2TOOL_DIR/sm2decrypt
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ -z $SM2TOOL_DIR ]; then
+        echo "Error: Environment variable SM2TOOL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $SM2ENCRYPT ]; then
+        echo "Error: sm2encrypt not found"
+        return $FAIL
+    fi
+    if [ ! -f $SM2DECRYPT ]; then
+        echo "Error: sm2decrypt not found"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+is_engine_available() {
+    if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
+        echo "Error: engine unavailable"
+        return $FAIL
+    fi
+    return $PASS
+}    
+
+print_configuration() {
+    echo "DEBUG           $DEBUG         "
+    echo "VALIDATE_SETUP  $VALIDATE_SETUP"
+    echo "ENGINE_ID_28    $ENGINE_ID_28  "
+    echo "KERNEL_MODULE   $KERNEL_MODULE "
+    echo "OPENSSL         $OPENSSL       "
+    echo "SM2ENCRYPT      $SM2ENCRYPT    "
+    echo "SM2DECRYPT      $SM2DECRYPT    "
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_SM2_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate private SM2 key:
+    # apps/openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:sm2 -out private.pem
+    # examine private SM2 key:
+    # openssl ec -in private.pem -noout -text
+    print=`${OPENSSL} genpkey \
+        $parameter_engine \
+        -algorithm EC \
+        -pkeyopt ec_paramgen_curve:sm2 \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+    return $ret
+}
+
+derive_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate public SM2 key:
+    # openssl ec -pubout -in private.pem -out public.pem
+    # examine public SM2 key:
+    # openssl ec -noout -text -inform PEM -in public.pem -pubin
+    print=`${OPENSSL} ec \
+        $parameter_engine \
+        -pubout \
+        -in $private_key_file \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+    return $ret
+}
+
+sm2_encrypt() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local message_file=$2
+    local public_key_file=$3
+    local output_file=$4
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// sm2_encrypt $2 $3 $4" >> sm2-encrypt-and-decrypt_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=--engine=$ENGINE_ID_28
+    print=`$valgrind $SM2ENCRYPT \
+        $parameter_engine \
+        --message $message_file \
+        --key $public_key_file \
+        --out $output_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> sm2-encrypt-and-decrypt_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+sm2_decrypt() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local encrypted_file=$2
+    local private_key_file=$3
+    local output_file=$4
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// sm2_decrypt $2 $3 $4" >> sm2-encrypt-and-decrypt_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=--engine=$ENGINE_ID_28
+    print=`$SM2DECRYPT \
+        $parameter_engine \
+        --encrypted $encrypted_file \
+        --key $private_key_file \
+        --out $output_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> sm2-encrypt-and-decrypt_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_sm2_encrypt_and_decrypt_positive() {
+    local use_engine_encrypt=$1
+    local use_engine_decrypt=$2
+    cleanup test.file private.pem public.pem test.file.enc test.file.dec
+    create_test_file test.file 50
+    create_SM2_private_key false private.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private.pem public.pem
+    [ $? -ne 0 ] && return 2
+    sm2_encrypt $use_engine_encrypt test.file public.pem test.file.enc
+    [ $? -ne 0 ] && return 3
+    sm2_decrypt $use_engine_decrypt test.file.enc private.pem test.file.dec
+    [ $? -ne 0 ] && return 4
+    cmp -s test.file test.file.dec
+    [ $? -ne 0 ] && return 5
+    return $PASS
+}
+
+test_sm2_encrypt_and_decrypt_negative() {
+    local use_engine_encrypt=$1
+    local use_engine_decrypt=$2
+    cleanup test.file private.pem private_2.pem public_2.pem test.file.enc test.file.dec
+    create_test_file test.file 50
+    create_SM2_private_key false private.pem
+    [ $? -ne 0 ] && return 1
+    create_SM2_private_key false private_2.pem
+    [ $? -ne 0 ] && return 2
+    derive_public_key false private_2.pem public_2.pem
+    [ $? -ne 0 ] && return 3
+    sm2_encrypt $use_engine_encrypt test.file public_2.pem test.file.enc
+    [ $? -ne 0 ] && return 4
+    sm2_decrypt $use_engine_decrypt test.file.enc private.pem test.file.dec
+    [ $? -eq 0 ] && return 5 # THIS IS A NEGATIVE TEST
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    echo "Test: SM2 encrypt and decrypt"
+    # arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null; then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    # validation
+    if [ $VALIDATE_SETUP == true ]; then
+        echo "validate setup"
+        validate_environment
+        [ $? -eq $FAIL ] && exit 1
+        is_engine_available
+        [ $? -eq $FAIL ] && exit 1
+        print_configuration
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK sm2-encrypt-and-decrypt valgrind results - $DATESTAMP" > sm2-encrypt-and-decrypt_$DATESTAMP.log
+    fi
+
+    # tests:
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="SM2 encrypt and decrypt using a matching pub key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_positive false false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="SM2 encrypt and decrypt using a matching pub key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_positive true true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="SM2 encrypt and decrypt using a matching pub key (engine, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_positive true false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 4 ]; then
+        test_name="SM2 encrypt and decrypt using a matching pub key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_positive false true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 5 ]; then
+        test_name="SM2 encrypt and decrypt using an unmatching pub key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_negative false false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 6 ]; then
+        test_name="SM2 encrypt and decrypt using an unmatching pub key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_encrypt_and_decrypt_negative true true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    exit 0
+}
+
+main "$@"

+ 368 - 0
rambus_sec_lib/bin/EIP28_scripts/sm2-sign-and-verify.sh

@@ -0,0 +1,368 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+#
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+# 
+# Tests:
+#     1. SM2 sign (openssl) and verify (openssl) / matching private and public key
+#     2. SM2 sign (engine) and verify (engine) / matching private and public key
+#     3. SM2 sign (engine) and verify (openssl) / matching private and public key
+#     4. SM2 sign (openssl) and verify (engine) / matching private and public key
+#     5. SM2 sign (openssl) and verify (openssl) / unmatching private and public key
+#     6. SM2 sign (engine) and verify (engine) / unmatching private and public key
+#
+# Setup:
+# 1. Configure the openssl:     export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:           export OPENSSL_ENGINES=/path/to/engines
+# 3. Configure the SM2 tool:    export SM2TOOL_DIR="/path/to/sm2"
+#
+# Usage:
+#    run all tests:    bash sm2-sign-and-verify.sh
+#    run a test:       bash sm2-sign-and-verify.sh <test number>
+#
+# Date:        23/7/2021 
+##############################################################################
+
+############################ constants ############################
+PASS=0
+FAIL=1
+DEBUG=false
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+SM2SIGN=$SM2TOOL_DIR/sm2sign
+SM2VERIFY=$SM2TOOL_DIR/sm2verify
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ -z $SM2TOOL_DIR ]; then
+        echo "Error: Environment variable SM2TOOL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $SM2SIGN ]; then
+        echo "Error: sm2sign not found"
+        return $FAIL
+    fi
+    if [ ! -f $SM2VERIFY ]; then
+        echo "Error: sm2verify not found"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+print_configuration() {
+    echo "DEBUG           $DEBUG         "
+    echo "VALIDATE_SETUP  $VALIDATE_SETUP"
+    echo "ENGINE_ID_28    $ENGINE_ID_28  "
+    echo "KERNEL_MODULE   $KERNEL_MODULE "
+    echo "OPENSSL         $OPENSSL       "
+    echo "SM2SIGN         $SM2SIGN       "
+    echo "SM2VERIFY       $SM2VERIFY     "
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_SM2_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate private SM2 key:
+    # apps/openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:sm2 -out private.pem
+    # examine private SM2 key:
+    # openssl ec -in private.pem -noout -text
+    print=`$valgrind ${OPENSSL} genpkey \
+        $parameter_engine \
+        -algorithm EC \
+        -pkeyopt ec_paramgen_curve:sm2 \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+    return $ret
+}
+
+derive_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate public SM2 key:
+    # openssl ec -pubout -in private.pem -out public.pem
+    # examine public SM2 key:
+    # openssl ec -noout -text -inform PEM -in public.pem -pubin
+    print=`${OPENSSL} ec \
+        $parameter_engine \
+        -pubout \
+        -in $private_key_file \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+    return $ret
+}
+
+hash_the_file_and_sign_the_hash() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local message_file=$2
+    local private_key_file=$3
+    local sm2id=$4
+    local signature_file=$5
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// hash_the_file_and_sign_the_hash $2 $3 $4 $5" >> sm2-sign-and-verify_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=--engine=$ENGINE_ID_28
+    print=`$valgrind $SM2SIGN \
+        $parameter_engine \
+        --message $message_file \
+        --key $private_key_file \
+        --id $sm2id \
+        --signature $signature_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> sm2-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+hash_the_file_and_validate_the_signature() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local message_file=$2
+    local public_key_file=$3
+    local sm2id=$4
+    local signature_file=$5
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// hash_the_file_and_validate_the_signature $2 $3 $4 $5" >> sm2-sign-and-verify_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=--engine=$ENGINE_ID_28
+    print=`$valgrind $SM2VERIFY \
+        $parameter_engine \
+        --message $message_file \
+        --key $public_key_file \
+        --id $sm2id \
+        --signature $signature_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> sm2-sign-and-verify_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_sm2_sign_and_verify_positive() {
+    local use_engine_sign=$1
+    local use_engine_verify=$2
+    cleanup test.file private.pem public.pem signature.bin test.file.hash
+    create_test_file test.file 50
+    create_SM2_private_key false private.pem
+    [ $? -ne 0 ] && return 1
+    hash_the_file_and_sign_the_hash $use_engine_sign test.file private.pem 1234letter signature.bin
+    [ $? -ne 0 ] && return 2
+    derive_public_key false private.pem public.pem
+    [ $? -ne 0 ] && return 3
+    hash_the_file_and_validate_the_signature $use_engine_verify test.file public.pem 1234letter signature.bin
+    [ $? -ne 0 ] && return 4
+    return $PASS
+}
+
+test_sm2_sign_and_verify_negative() {
+    local use_engine_sign=$1
+    local use_engine_verify=$2
+    cleanup test.file private.pem private_2.pem public_2.pem signature.bin test.file.hash
+    create_test_file test.file 50
+    create_SM2_private_key false private.pem
+    [ $? -ne 0 ] && return 1
+    hash_the_file_and_sign_the_hash $use_engine_sign test.file private.pem 1234letter signature.bin
+    [ $? -ne 0 ] && return 2
+    create_SM2_private_key false private_2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private_2.pem public_2.pem
+    [ $? -ne 0 ] && return 4
+    hash_the_file_and_validate_the_signature $use_engine_verify test.file public_2.pem 1234letter signature.bin
+    [ $? -eq 0 ] && return 5 # THIS IS A NEGATIVE TEST
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    echo "Test: SM2 sign and verify"
+    # arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null;  then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    # validation
+    if [ $VALIDATE_SETUP == true ]; then
+        echo "validate setup"
+        validate_environment
+        [ $? -eq $FAIL ] && exit 1
+        print_configuration
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK sm2-sign-and-verify valgrind results - $DATESTAMP" > sm2-sign-and-verify_$DATESTAMP.log
+    fi
+
+    # tests:
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="SM2 sign and verify using a matching pub key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_positive false false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="SM2 sign and verify using a matching pub key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_positive true true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="SM2 sign and verify using a matching pub key (engine, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_positive true false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 4 ]; then
+        test_name="SM2 sign and verify using a matching pub key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_positive false true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 5 ]; then
+        test_name="SM2 sign and verify using an unmatching pub key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_negative false false
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 6 ]; then
+        test_name="SM2 sign and verify using an unmatching pub key (engine, engine)"
+        printf "Test %s: " "$test_name"
+        test_sm2_sign_and_verify_negative true true
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+    fi
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    exit 0
+}
+
+main "$@"

+ 37 - 0
rambus_sec_lib/bin/EIP28_scripts/test-all.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+
+# This script runs all the PKA EIP 28 openssl engine tests.
+#
+# Usage:
+#    run:    bash test-all.sh
+#
+# Date:        12/8/2021
+
+# get script directory (current directory)
+TEST_DIR="$(dirname "$(readlink -f "$0")")"
+
+if [ "$1" = "-v" ]; then
+echo "yup"
+    VALGRIND_PARM=$1
+fi
+
+# run all test scripts
+bash $TEST_DIR/edcsa-sign-and-verify.sh $VALGRIND_PARM
+bash $TEST_DIR/sm2-sign-and-verify.sh $VALGRIND_PARM
+bash $TEST_DIR/sm2-encrypt-and-decrypt.sh $VALGRIND_PARM
+bash $TEST_DIR/dh-key-agreement.sh $VALGRIND_PARM
+bash $TEST_DIR/ecdh-key-agreement.sh $VALGRIND_PARM
+bash $TEST_DIR/x25519-key-agreement.sh $VALGRIND_PARM
+bash $TEST_DIR/rsa-encrypt-decrypt-sign-verify.sh $VALGRIND_PARM

+ 318 - 0
rambus_sec_lib/bin/EIP28_scripts/x25519-key-agreement.sh

@@ -0,0 +1,318 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+#
+# This script tests openssl engine e_eip28pka.so with openssl 1.1.1k 
+# running on an x86 host and a PCIe virtex HW with the PKA module.
+#
+# Tests:
+#   1. key agreement, curve X25519, matching private key public peer key (openssl, openssl)
+#   2. key agreement, curve X25519, matching private key public peer key (engine, engine)
+#   3. Key agreement, curve X25519, unmatching private key public peer key (openssl, engine)
+#
+# Setup:
+# 1. Configure the openssl:   export OPENSSL_DIR="/path/to/openssl-1.1.1k"
+# 2. Set engine path:         export OPENSSL_ENGINES=/path/to/engines
+# 
+# Usage:
+#    run all tests:    bash x25519-key-agreement.sh
+#    run a test:       bash x25519-key-agreement.sh <test number>
+#
+# Date:        12/8/2021
+##############################################################################
+
+############################ constants ############################
+PASS=0
+FAIL=1
+DEBUG=false
+VALIDATE_SETUP=true
+ENGINE_ID_28=eip28pka
+KERNEL_MODULE=umpci_k
+OPENSSL=$OPENSSL_DIR/apps/openssl
+DATESTAMP=$(date +%y%m%d_%H%M)
+TEMPFILE=tempfile.txt
+VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
+
+############################ functions ############################
+print_function() {
+    echo "${FUNCNAME[1]}"
+}
+
+print_openssl_details() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} version
+}
+
+validate_environment() {
+    [ $DEBUG = true ] && print_function
+    if [ -z $OPENSSL_DIR ]; then
+        echo "Error: Environment variable OPENSSL_DIR is undefined"
+        return $FAIL
+    fi
+    if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
+        echo "Error: openssl client not found"
+        return $FAIL
+    fi
+    if [ -z $OPENSSL_ENGINES ]; then
+        echo "Error: Environment variable OPENSSL_ENGINES is undefined"
+        return $FAIL
+    fi
+    if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
+        echo "Error: kernel module $KERNEL_MODULE not found"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_engine_capabilities() {
+    [ $DEBUG = true ] && print_function
+    ${OPENSSL} engine -c $ENGINE_ID_28
+}
+
+is_engine_available() {
+    if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
+        echo "Error: engine unavailable"
+        return $FAIL
+    fi
+    return $PASS
+}
+
+print_configuration() {
+    echo "DEBUG           $DEBUG         "
+    echo "VALIDATE_SETUP  $VALIDATE_SETUP"
+    echo "ENGINE_ID_28    $ENGINE_ID_28  "
+    echo "KERNEL_MODULE   $KERNEL_MODULE "
+    echo "OPENSSL         $OPENSSL       "
+}
+
+create_test_file() {
+    local filename=$1
+    local length=$2
+    [ $DEBUG = true ] && print_function
+    echo $(${OPENSSL} rand -base64 $length) > $filename
+    [ $DEBUG = true ] && cat $filename
+}
+
+create_X25519_private_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate private key:
+    # openssl genpkey -algorithm X25519 -out private.pem
+    # examine private key:
+    # openssl ec -in private.pem -noout -text
+    print=`${OPENSSL} genpkey \
+        $parameter_engine \
+        -algorithm X25519 \
+        -out $private_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $private_key_file
+    return $ret
+}
+
+derive_public_key() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_file=$3
+    local parameter_engine
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    local ret
+    local print
+    # generate public key:
+    # openssl ec -pubout -in private.pem -out public.pem
+    # examine public key:
+    # openssl pkey -noout -text -inform PEM -in public.pem -pubin
+    print=`${OPENSSL} pkey \
+        $parameter_engine \
+        -pubout \
+        -in $private_key_file \
+        -out $public_key_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "return: $ret"
+    [ $DEBUG = true ] && cat $public_key_file
+    return $ret
+}
+
+derive_shared_secret() {
+    [ $DEBUG = true ] && print_function
+    local engine=$1
+    local private_key_file=$2
+    local public_key_peer_file=$3
+    local output_secert_file=$4
+    local ret
+    local print
+    local parameter_engine
+
+    if [ $engine == true ]; then
+        local valgrind=$VALGRIND
+        local dovalgrind=$DO_VALGRIND
+    fi
+
+    if [ $dovalgrind ]; then
+        echo "// derive_shared_secret $2 $3 $4" >> x25519-key-agreement_$DATESTAMP.log
+    fi
+
+    [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
+    # openssl pkeyutl -derive -inkey alice.pem -peerkey bob.pub -out alicebob.key
+    print=`$valgrind $OPENSSL pkeyutl \
+        -derive \
+        $parameter_engine \
+        -inkey $private_key_file \
+        -peerkey $public_key_peer_file \
+        -out $output_secert_file 2>&1`
+    ret=$?
+    [ $DEBUG = true ] && echo "*********************** START *******************************"
+    [ $DEBUG = true ] && echo "$print"
+    [ $DEBUG = true ] && echo "*********************** END *******************************"
+    [ $DEBUG = true ] && echo "return: $ret"
+
+    if [ $dovalgrind ]; then
+        cat $TEMPFILE >> x25519-key-agreement_$DATESTAMP.log
+    fi
+
+    return $ret
+}
+
+cleanup() {
+    [ $DEBUG = true ] && print_function
+    for f in "$@"; do
+        [ -f "$f" ] && rm $f 
+    done
+}
+
+test_key_exchange_positive () {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_X25519_private_key false private1.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 2
+    create_X25519_private_key false private2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 4
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 5
+    derive_shared_secret $use_engine_2 private2.pem public1.pem secret2.bin
+    [ $? -ne 0 ] && return 6
+    cmp -s secret1.bin secret2.bin
+    [ $? -ne 0 ] && return 7
+    return $PASS
+}
+
+test_key_exchange_negative() {
+    local use_engine_1=$1
+    local use_engine_2=$2
+    cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin 
+    create_X25519_private_key false private1.pem
+    [ $? -ne 0 ] && return 1
+    derive_public_key false private1.pem public1.pem
+    [ $? -ne 0 ] && return 2
+    create_X25519_private_key false private2.pem
+    [ $? -ne 0 ] && return 3
+    derive_public_key false private2.pem public2.pem
+    [ $? -ne 0 ] && return 4
+    create_X25519_private_key false $curve private3.pem
+    [ $? -ne 0 ] && return 5
+    derive_public_key false private3.pem public3.pem
+    [ $? -ne 0 ] && return 6
+    derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
+    [ $? -ne 0 ] && return 7
+    derive_shared_secret $use_engine_2 private2.pem public3.pem secret2.bin
+    [ $? -ne 0 ] && return 8
+    cmp -s secret1.bin secret2.bin
+    [ $? -eq 0 ] && return 6
+    return $PASS
+}
+
+############################ main ############################
+
+main () {
+    echo "Test: x25519 key agreement"
+    # arguments
+    run_all=false
+    run_test_number=0
+    if [ "$1" -eq "$1" ] 2>/dev/null; then
+        run_test_number=$1
+        echo "Run test number $test_number"
+    else
+        run_all=true
+        echo "Run all tests"
+    fi
+    # validation
+    if [ $VALIDATE_SETUP == true ]; then
+        echo "validate setup"
+        validate_environment
+        [ $? -eq $FAIL ] && exit 1
+        is_engine_available
+        [ $? -eq $FAIL ] && exit 1
+        print_configuration
+        print_openssl_details
+        print_engine_capabilities
+    fi
+
+    if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
+        DO_VALGRIND=1
+        VALGRIND=$VALGRIND_CMD
+        echo "// OS_IK x25519-key-agreement valgrind results - $DATESTAMP" > x25519-key-agreement_$DATESTAMP.log
+    fi
+
+    # tests:
+    tests_run=0
+    tests_pass=0
+    tests_total=3
+    if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
+        test_name="Key agreement, curve X25519, matching private key public peer key (openssl, openssl)"
+        printf "Test %s: " "$test_name"
+        test_key_exchange_positive false false X25519
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
+        test_name="Key agreement, curve X25519, matching private key public peer key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_key_exchange_positive false true X25519
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
+        test_name="Key agreement, curve X25519, unmatching private key public peer key (openssl, engine)"
+        printf "Test %s: " "$test_name"
+        test_key_exchange_negative false true X25519
+        result=$?
+        [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
+        if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
+        (( tests_run++ ))
+    fi
+    echo "tests: $tests_total run: $tests_run passed: $tests_pass"
+
+    if [ $DO_VALGRIND ]; then
+        rm $TEMPFILE
+    fi
+
+    exit 0
+}
+
+main "$@"

+ 51 - 0
rambus_sec_lib/bin/Makefile

@@ -0,0 +1,51 @@
+##############################################################################
+# Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
+# All rights reserved. Unauthorized use (including, without limitation,
+# distribution and copying) is strictly prohibited. All use requires,
+# and is subject to, explicit written authorization and nondisclosure
+# Rambus, Inc. and/or its subsidiaries
+#
+# For more information or support, please go to our online support system at
+# https://sipsupport.rambus.com.
+# In case you do not have an account for this system, please send an e-mail
+# to sipsupport@rambus.com.
+##############################################################################
+# check dependencies
+ifndef OPENSSL_DIR
+$(error OPENSSL_DIR is not set)
+endif
+
+# default
+all: cipher digest
+
+# cipher executable
+cipher:
+	${CROSS_COMPILE}gcc -O0 \
+	-ggdb \
+	 ../src/cipher.c \
+	-Wl,-rpath=usr/lib64,-rpath=${OPENSSL_DIR} \
+	-I${OPENSSL_DIR}/include \
+	-L${OPENSSL_DIR} \
+	-lcrypto \
+	-o cipher
+	ls -la cipher
+
+# digest executable
+digest:
+	${CROSS_COMPILE}gcc -O0 \
+	-ggdb \
+	 ../src/digest.c \
+	-Wl,-rpath=usr/lib64,-rpath=${OPENSSL_DIR} \
+	-I${OPENSSL_DIR}/include \
+	-L${OPENSSL_DIR} \
+	-lcrypto \
+	-o digest
+	ls -la digest
+
+clean:
+	rm cipher
+	rm digest
+
+.PHONY: info
+info:
+	$(info $$OPENSSL_DIR is [${OPENSSL_DIR}])

+ 232 - 0
rambus_sec_lib/bin/c_rehash

@@ -0,0 +1,232 @@
+#!/usr/bin/env perl
+
+# WARNING: do not edit!
+# Generated by Makefile from tools/c_rehash.in
+# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# Perl c_rehash script, scan all files in a directory
+# and add symbolic links to their hash values.
+
+my $dir = "";
+my $prefix = "/home/lw312886/project/rambus_ddk/light_sec_driver/openssl-1.1.1k/openssl_instasll";
+
+my $errorcount = 0;
+my $openssl = $ENV{OPENSSL} || "openssl";
+my $pwd;
+my $x509hash = "-subject_hash";
+my $crlhash = "-hash";
+my $verbose = 0;
+my $symlink_exists=eval {symlink("",""); 1};
+my $removelinks = 1;
+
+##  Parse flags.
+while ( $ARGV[0] =~ /^-/ ) {
+    my $flag = shift @ARGV;
+    last if ( $flag eq '--');
+    if ( $flag eq '-old') {
+	    $x509hash = "-subject_hash_old";
+	    $crlhash = "-hash_old";
+    } elsif ( $flag eq '-h' || $flag eq '-help' ) {
+	    help();
+    } elsif ( $flag eq '-n' ) {
+	    $removelinks = 0;
+    } elsif ( $flag eq '-v' ) {
+	    $verbose++;
+    }
+    else {
+	    print STDERR "Usage error; try -h.\n";
+	    exit 1;
+    }
+}
+
+sub help {
+	print "Usage: c_rehash [-old] [-h] [-help] [-v] [dirs...]\n";
+	print "   -old use old-style digest\n";
+	print "   -h or -help print this help text\n";
+	print "   -v print files removed and linked\n";
+	exit 0;
+}
+
+eval "require Cwd";
+if (defined(&Cwd::getcwd)) {
+	$pwd=Cwd::getcwd();
+} else {
+	$pwd=`pwd`;
+	chomp($pwd);
+}
+
+# DOS/Win32 or Unix delimiter?  Prefix our installdir, then search.
+my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';
+$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : "");
+
+if (! -x $openssl) {
+	my $found = 0;
+	foreach (split /$path_delim/, $ENV{PATH}) {
+		if (-x "$_/$openssl") {
+			$found = 1;
+			$openssl = "$_/$openssl";
+			last;
+		}	
+	}
+	if ($found == 0) {
+		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
+		exit 0;
+	}
+}
+
+if (@ARGV) {
+	@dirlist = @ARGV;
+} elsif ($ENV{SSL_CERT_DIR}) {
+	@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
+} else {
+	$dirlist[0] = "$dir/certs";
+}
+
+if (-d $dirlist[0]) {
+	chdir $dirlist[0];
+	$openssl="$pwd/$openssl" if (!-x $openssl);
+	chdir $pwd;
+}
+
+foreach (@dirlist) {
+	if (-d $_ ) {
+            if ( -w $_) {
+		hash_dir($_);
+            } else {
+                print "Skipping $_, can't write\n";
+                $errorcount++;
+            }
+	}
+}
+exit($errorcount);
+
+sub hash_dir {
+	my %hashlist;
+	print "Doing $_[0]\n";
+	chdir $_[0];
+	opendir(DIR, ".");
+	my @flist = sort readdir(DIR);
+	closedir DIR;
+	if ( $removelinks ) {
+		# Delete any existing symbolic links
+		foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
+			if (-l $_) {
+				print "unlink $_" if $verbose;
+				unlink $_ || warn "Can't unlink $_, $!\n";
+			}
+		}
+	}
+	FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
+		# Check to see if certificates and/or CRLs present.
+		my ($cert, $crl) = check_file($fname);
+		if (!$cert && !$crl) {
+			print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
+			next;
+		}
+		link_hash_cert($fname) if ($cert);
+		link_hash_crl($fname) if ($crl);
+	}
+}
+
+sub check_file {
+	my ($is_cert, $is_crl) = (0,0);
+	my $fname = $_[0];
+	open IN, $fname;
+	while(<IN>) {
+		if (/^-----BEGIN (.*)-----/) {
+			my $hdr = $1;
+			if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+				$is_cert = 1;
+				last if ($is_crl);
+			} elsif ($hdr eq "X509 CRL") {
+				$is_crl = 1;
+				last if ($is_cert);
+			}
+		}
+	}
+	close IN;
+	return ($is_cert, $is_crl);
+}
+
+
+# Link a certificate to its subject name hash value, each hash is of
+# the form <hash>.<n> where n is an integer. If the hash value already exists
+# then we need to up the value of n, unless its a duplicate in which
+# case we skip the link. We check for duplicates by comparing the
+# certificate fingerprints
+
+sub link_hash_cert {
+		my $fname = $_[0];
+		$fname =~ s/\"/\\\"/g;
+		my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if ($hashlist{"$hash.$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".$suffix";
+		if ($symlink_exists) {
+			print "link $fname -> $hash\n" if $verbose;
+			symlink $fname, $hash || warn "Can't symlink, $!";
+		} else {
+			print "copy $fname -> $hash\n" if $verbose;
+                        if (open($in, "<", $fname)) {
+                            if (open($out,">", $hash)) {
+                                print $out $_ while (<$in>);
+                                close $out;
+                            } else {
+                                warn "can't open $hash for write, $!";
+                            }
+                            close $in;
+                        } else {
+                            warn "can't open $fname for read, $!";
+                        }
+		}
+		$hashlist{$hash} = $fprint;
+}
+
+# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
+
+sub link_hash_crl {
+		my $fname = $_[0];
+		$fname =~ s/'/'\\''/g;
+		my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
+		chomp $hash;
+		chomp $fprint;
+		$fprint =~ s/^.*=//;
+		$fprint =~ tr/://d;
+		my $suffix = 0;
+		# Search for an unused hash filename
+		while(exists $hashlist{"$hash.r$suffix"}) {
+			# Hash matches: if fingerprint matches its a duplicate cert
+			if ($hashlist{"$hash.r$suffix"} eq $fprint) {
+				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
+				return;
+			}
+			$suffix++;
+		}
+		$hash .= ".r$suffix";
+		if ($symlink_exists) {
+			print "link $fname -> $hash\n" if $verbose;
+			symlink $fname, $hash || warn "Can't symlink, $!";
+		} else {
+			print "cp $fname -> $hash\n" if $verbose;
+			system ("cp", $fname, $hash);
+                        warn "Can't copy, $!" if ($? >> 8) != 0;
+		}
+		$hashlist{$hash} = $fprint;
+}

BIN
rambus_sec_lib/bin/cipher


BIN
rambus_sec_lib/bin/digest


BIN
rambus_sec_lib/bin/openssl


BIN
rambus_sec_lib/bin/sm2decrypt


BIN
rambus_sec_lib/bin/sm2encrypt


BIN
rambus_sec_lib/bin/sm2sign


BIN
rambus_sec_lib/bin/sm2verify


+ 92 - 0
rambus_sec_lib/include/openssl/aes.h

@@ -0,0 +1,92 @@
+/*
+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_AES_H
+# define HEADER_AES_H
+
+# include <openssl/opensslconf.h>
+
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define AES_ENCRYPT     1
+# define AES_DECRYPT     0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+# define AES_MAXNR 14
+# define AES_BLOCK_SIZE 16
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+# ifdef AES_LONG
+    unsigned long rd_key[4 * (AES_MAXNR + 1)];
+# else
+    unsigned int rd_key[4 * (AES_MAXNR + 1)];
+# endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num);
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        const AES_KEY *key2, const unsigned char *ivec,
+                        const int enc);
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+                 unsigned char *out,
+                 const unsigned char *in, unsigned int inlen);
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+                   unsigned char *out,
+                   const unsigned char *in, unsigned int inlen);
+
+
+# ifdef  __cplusplus
+}
+# endif
+
+#endif

+ 886 - 0
rambus_sec_lib/include/openssl/asn1.h

@@ -0,0 +1,886 @@
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_ASN1_H
+# define HEADER_ASN1_H
+
+# include <time.h>
+# include <openssl/e_os2.h>
+# include <openssl/opensslconf.h>
+# include <openssl/bio.h>
+# include <openssl/safestack.h>
+# include <openssl/asn1err.h>
+# include <openssl/symhacks.h>
+
+# include <openssl/ossl_typ.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define V_ASN1_UNIVERSAL                0x00
+# define V_ASN1_APPLICATION              0x40
+# define V_ASN1_CONTEXT_SPECIFIC         0x80
+# define V_ASN1_PRIVATE                  0xc0
+
+# define V_ASN1_CONSTRUCTED              0x20
+# define V_ASN1_PRIMITIVE_TAG            0x1f
+# define V_ASN1_PRIMATIVE_TAG /*compat*/ V_ASN1_PRIMITIVE_TAG
+
+# define V_ASN1_APP_CHOOSE               -2/* let the recipient choose */
+# define V_ASN1_OTHER                    -3/* used in ASN1_TYPE */
+# define V_ASN1_ANY                      -4/* used in ASN1 template code */
+
+# define V_ASN1_UNDEF                    -1
+/* ASN.1 tag values */
+# define V_ASN1_EOC                      0
+# define V_ASN1_BOOLEAN                  1 /**/
+# define V_ASN1_INTEGER                  2
+# define V_ASN1_BIT_STRING               3
+# define V_ASN1_OCTET_STRING             4
+# define V_ASN1_NULL                     5
+# define V_ASN1_OBJECT                   6
+# define V_ASN1_OBJECT_DESCRIPTOR        7
+# define V_ASN1_EXTERNAL                 8
+# define V_ASN1_REAL                     9
+# define V_ASN1_ENUMERATED               10
+# define V_ASN1_UTF8STRING               12
+# define V_ASN1_SEQUENCE                 16
+# define V_ASN1_SET                      17
+# define V_ASN1_NUMERICSTRING            18 /**/
+# define V_ASN1_PRINTABLESTRING          19
+# define V_ASN1_T61STRING                20
+# define V_ASN1_TELETEXSTRING            20/* alias */
+# define V_ASN1_VIDEOTEXSTRING           21 /**/
+# define V_ASN1_IA5STRING                22
+# define V_ASN1_UTCTIME                  23
+# define V_ASN1_GENERALIZEDTIME          24 /**/
+# define V_ASN1_GRAPHICSTRING            25 /**/
+# define V_ASN1_ISO64STRING              26 /**/
+# define V_ASN1_VISIBLESTRING            26/* alias */
+# define V_ASN1_GENERALSTRING            27 /**/
+# define V_ASN1_UNIVERSALSTRING          28 /**/
+# define V_ASN1_BMPSTRING                30
+
+/*
+ * NB the constants below are used internally by ASN1_INTEGER
+ * and ASN1_ENUMERATED to indicate the sign. They are *not* on
+ * the wire tag values.
+ */
+
+# define V_ASN1_NEG                      0x100
+# define V_ASN1_NEG_INTEGER              (2 | V_ASN1_NEG)
+# define V_ASN1_NEG_ENUMERATED           (10 | V_ASN1_NEG)
+
+/* For use with d2i_ASN1_type_bytes() */
+# define B_ASN1_NUMERICSTRING    0x0001
+# define B_ASN1_PRINTABLESTRING  0x0002
+# define B_ASN1_T61STRING        0x0004
+# define B_ASN1_TELETEXSTRING    0x0004
+# define B_ASN1_VIDEOTEXSTRING   0x0008
+# define B_ASN1_IA5STRING        0x0010
+# define B_ASN1_GRAPHICSTRING    0x0020
+# define B_ASN1_ISO64STRING      0x0040
+# define B_ASN1_VISIBLESTRING    0x0040
+# define B_ASN1_GENERALSTRING    0x0080
+# define B_ASN1_UNIVERSALSTRING  0x0100
+# define B_ASN1_OCTET_STRING     0x0200
+# define B_ASN1_BIT_STRING       0x0400
+# define B_ASN1_BMPSTRING        0x0800
+# define B_ASN1_UNKNOWN          0x1000
+# define B_ASN1_UTF8STRING       0x2000
+# define B_ASN1_UTCTIME          0x4000
+# define B_ASN1_GENERALIZEDTIME  0x8000
+# define B_ASN1_SEQUENCE         0x10000
+/* For use with ASN1_mbstring_copy() */
+# define MBSTRING_FLAG           0x1000
+# define MBSTRING_UTF8           (MBSTRING_FLAG)
+# define MBSTRING_ASC            (MBSTRING_FLAG|1)
+# define MBSTRING_BMP            (MBSTRING_FLAG|2)
+# define MBSTRING_UNIV           (MBSTRING_FLAG|4)
+# define SMIME_OLDMIME           0x400
+# define SMIME_CRLFEOL           0x800
+# define SMIME_STREAM            0x1000
+    struct X509_algor_st;
+DEFINE_STACK_OF(X509_ALGOR)
+
+# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
+/*
+ * This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should be
+ * inserted in the memory buffer
+ */
+# define ASN1_STRING_FLAG_NDEF 0x010
+
+/*
+ * This flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been accessed.
+ * The flag will be reset when content has been written to it.
+ */
+
+# define ASN1_STRING_FLAG_CONT 0x020
+/*
+ * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+# define ASN1_STRING_FLAG_MSTRING 0x040
+/* String is embedded and only content should be freed */
+# define ASN1_STRING_FLAG_EMBED 0x080
+/* String should be parsed in RFC 5280's time format */
+# define ASN1_STRING_FLAG_X509_TIME 0x100
+/* This is the base type that holds just about everything :-) */
+struct asn1_string_st {
+    int length;
+    int type;
+    unsigned char *data;
+    /*
+     * The value of the following field depends on the type being held.  It
+     * is mostly being used for BIT_STRING so if the input data has a
+     * non-zero 'unused bits' value, it will be handled correctly
+     */
+    long flags;
+};
+
+/*
+ * ASN1_ENCODING structure: this is used to save the received encoding of an
+ * ASN1 type. This is useful to get round problems with invalid encodings
+ * which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st {
+    unsigned char *enc;         /* DER encoding */
+    long len;                   /* Length of encoding */
+    int modified;               /* set to 1 if 'enc' is invalid */
+} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+# define ASN1_LONG_UNDEF 0x7fffffffL
+
+# define STABLE_FLAGS_MALLOC     0x01
+/*
+ * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted
+ * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting
+ * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias
+ * STABLE_FLAGS_CLEAR to reflect this.
+ */
+# define STABLE_FLAGS_CLEAR      STABLE_FLAGS_MALLOC
+# define STABLE_NO_MASK          0x02
+# define DIRSTRING_TYPE  \
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+    int nid;
+    long minsize;
+    long maxsize;
+    unsigned long mask;
+    unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DEFINE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+# define ub_name                         32768
+# define ub_common_name                  64
+# define ub_locality_name                128
+# define ub_state_name                   128
+# define ub_organization_name            64
+# define ub_organization_unit_name       64
+# define ub_title                        64
+# define ub_email_address                128
+
+/*
+ * Declarations for template structures: for full definitions see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(itname)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(const type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(name)
+
+# define DECLARE_ASN1_NDEF_FUNCTION(name) \
+        int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+# define DECLARE_ASN1_FUNCTIONS_const(name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        type *name##_new(void); \
+        void name##_free(type *a);
+
+# define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+        DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                         const ASN1_PCTX *pctx);
+
+# define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+# define I2D_OF(type) int (*)(type *,unsigned char **)
+# define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+# define CHECKED_D2I_OF(type, d2i) \
+    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+# define CHECKED_I2D_OF(type, i2d) \
+    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+# define CHECKED_NEW_OF(type, xnew) \
+    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+# define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+# define CHECKED_PPTR_OF(type, p) \
+    ((void**) (1 ? p : (type**)0))
+
+# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/*-
+ * The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING;
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#  define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#  define DECLARE_ASN1_ITEM(name) \
+        OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+# else
+
+/*
+ * Platforms that can't easily handle shared global variables are declared as
+ * functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM *ASN1_ITEM_EXP (void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#  define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#  define DECLARE_ASN1_ITEM(name) \
+        const ASN1_ITEM * name##_it(void);
+
+# endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/*
+ * These determine which characters to escape: RFC2253 special characters,
+ * control characters and MSB set characters
+ */
+
+# define ASN1_STRFLGS_ESC_2253           1
+# define ASN1_STRFLGS_ESC_CTRL           2
+# define ASN1_STRFLGS_ESC_MSB            4
+
+/*
+ * This flag determines how we do escaping: normally RC2253 backslash only,
+ * set this to use backslash and quote.
+ */
+
+# define ASN1_STRFLGS_ESC_QUOTE          8
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+# define CHARTYPE_PRINTABLESTRING        0x10
+/* Character needs escaping if it is the first character */
+# define CHARTYPE_FIRST_ESC_2253         0x20
+/* Character needs escaping if it is the last character */
+# define CHARTYPE_LAST_ESC_2253          0x40
+
+/*
+ * NB the internal flags are safely reused below by flags handled at the top
+ * level.
+ */
+
+/*
+ * If this is set we convert all character strings to UTF8 first
+ */
+
+# define ASN1_STRFLGS_UTF8_CONVERT       0x10
+
+/*
+ * If this is set we don't attempt to interpret content: just assume all
+ * strings are 1 byte per character. This will produce some pretty odd
+ * looking output!
+ */
+
+# define ASN1_STRFLGS_IGNORE_TYPE        0x20
+
+/* If this is set we include the string type in the output */
+# define ASN1_STRFLGS_SHOW_TYPE          0x40
+
+/*
+ * This determines which strings to display and which to 'dump' (hex dump of
+ * content octets or DER encoding). We can only dump non character strings or
+ * everything. If we don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to the usual escaping
+ * options.
+ */
+
+# define ASN1_STRFLGS_DUMP_ALL           0x80
+# define ASN1_STRFLGS_DUMP_UNKNOWN       0x100
+
+/*
+ * These determine what 'dumping' does, we can dump the content octets or the
+ * DER encoding: both use the RFC2253 #XXXXX notation.
+ */
+
+# define ASN1_STRFLGS_DUMP_DER           0x200
+
+/*
+ * This flag specifies that RC2254 escaping shall be performed.
+ */
+#define ASN1_STRFLGS_ESC_2254           0x400
+
+/*
+ * All the string flags consistent with RFC2253, escaping control characters
+ * isn't essential in RFC2253 but it is advisable anyway.
+ */
+
+# define ASN1_STRFLGS_RFC2253    (ASN1_STRFLGS_ESC_2253 | \
+                                ASN1_STRFLGS_ESC_CTRL | \
+                                ASN1_STRFLGS_ESC_MSB | \
+                                ASN1_STRFLGS_UTF8_CONVERT | \
+                                ASN1_STRFLGS_DUMP_UNKNOWN | \
+                                ASN1_STRFLGS_DUMP_DER)
+
+DEFINE_STACK_OF(ASN1_INTEGER)
+
+DEFINE_STACK_OF(ASN1_GENERALSTRING)
+
+DEFINE_STACK_OF(ASN1_UTF8STRING)
+
+typedef struct asn1_type_st {
+    int type;
+    union {
+        char *ptr;
+        ASN1_BOOLEAN boolean;
+        ASN1_STRING *asn1_string;
+        ASN1_OBJECT *object;
+        ASN1_INTEGER *integer;
+        ASN1_ENUMERATED *enumerated;
+        ASN1_BIT_STRING *bit_string;
+        ASN1_OCTET_STRING *octet_string;
+        ASN1_PRINTABLESTRING *printablestring;
+        ASN1_T61STRING *t61string;
+        ASN1_IA5STRING *ia5string;
+        ASN1_GENERALSTRING *generalstring;
+        ASN1_BMPSTRING *bmpstring;
+        ASN1_UNIVERSALSTRING *universalstring;
+        ASN1_UTCTIME *utctime;
+        ASN1_GENERALIZEDTIME *generalizedtime;
+        ASN1_VISIBLESTRING *visiblestring;
+        ASN1_UTF8STRING *utf8string;
+        /*
+         * set and sequence are left complete and still contain the set or
+         * sequence bytes
+         */
+        ASN1_STRING *set;
+        ASN1_STRING *sequence;
+        ASN1_VALUE *asn1_value;
+    } value;
+} ASN1_TYPE;
+
+DEFINE_STACK_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+    int bitnum;
+    const char *lname;
+    const char *sname;
+} BIT_STRING_BITNAME;
+
+# define B_ASN1_TIME \
+                        B_ASN1_UTCTIME | \
+                        B_ASN1_GENERALIZEDTIME
+
+# define B_ASN1_PRINTABLE \
+                        B_ASN1_NUMERICSTRING| \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_T61STRING| \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_BIT_STRING| \
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING|\
+                        B_ASN1_SEQUENCE|\
+                        B_ASN1_UNKNOWN
+
+# define B_ASN1_DIRECTORYSTRING \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_TELETEXSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_UTF8STRING
+
+# define B_ASN1_DISPLAYTEXT \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_VISIBLESTRING| \
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(const ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t);
+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t);
+
+ASN1_OBJECT *ASN1_OBJECT_new(void);
+void ASN1_OBJECT_free(ASN1_OBJECT *a);
+int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp);
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DEFINE_STACK_OF(ASN1_OBJECT)
+
+ASN1_STRING *ASN1_STRING_new(void);
+void ASN1_STRING_free(ASN1_STRING *a);
+void ASN1_STRING_clear_free(ASN1_STRING *a);
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING *ASN1_STRING_type_new(int type);
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+  /*
+   * Since this is used to store all sorts of things, via macros, for now,
+   * make its data void *
+   */
+int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(const ASN1_STRING *x);
+DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x))
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n);
+int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
+                          const unsigned char *flags, int flags_len);
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent);
+int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
+                            BIT_STRING_BITNAME *tbl);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                                long length);
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+                               int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+                                               time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+                                               time_t t, int offset_day,
+                                               long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
+                          int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+                         int offset_day, long offset_sec);
+int ASN1_TIME_check(const ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
+                                                   ASN1_GENERALIZEDTIME **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str);
+int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm);
+int ASN1_TIME_normalize(ASN1_TIME *s);
+int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t);
+int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b);
+
+int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size);
+int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size);
+int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type);
+int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+                                const char *sn, const char *ln);
+
+int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a);
+int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r);
+int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a);
+int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn);
+
+int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a);
+int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r);
+
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+unsigned long ASN1_tag2bit(int tag);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+                    int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p, long len);
+int ASN1_const_check_infinite_end(const unsigned char **p, long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+                     int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+# define ASN1_dup_of(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(type, x)))
+
+# define ASN1_dup_of_const(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+# define M_ASN1_free_of(x, type) \
+                ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+# ifndef OPENSSL_NO_STDIO
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);
+
+#  define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+                        CHECKED_D2I_OF(type, d2i), \
+                        in, \
+                        CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);
+
+#  define ASN1_i2d_fp_of(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags);
+# endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in);
+
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);
+
+#  define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+                          CHECKED_D2I_OF(type, d2i), \
+                          in, \
+                          CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);
+
+#  define ASN1_i2d_bio_of(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags);
+int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                  unsigned char *buf, int off);
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump);
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write Netscape format cert */
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+                                  unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
+                                  unsigned char *data, int max_len);
+
+void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it);
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it,
+                            ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+                       int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in,
+                          long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+                       const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+void ASN1_add_stable_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf);
+int ASN1_str2mask(const char *str, unsigned long *pmask);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+# define ASN1_PCTX_FLAGS_SHOW_ABSENT             0x001
+/* Mark start and end of SEQUENCE */
+# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE           0x002
+/* Mark start and end of SEQUENCE/SET OF */
+# define ASN1_PCTX_FLAGS_SHOW_SSOF               0x004
+/* Show the ASN1 type of primitives */
+# define ASN1_PCTX_FLAGS_SHOW_TYPE               0x008
+/* Don't show ASN1 type of ANY */
+# define ASN1_PCTX_FLAGS_NO_ANY_TYPE             0x010
+/* Don't show ASN1 type of MSTRINGs */
+# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE         0x020
+/* Don't show field names in SEQUENCE */
+# define ASN1_PCTX_FLAGS_NO_FIELD_NAME           0x040
+/* Show structure names of each SEQUENCE field */
+# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME  0x080
+/* Don't show structure name even at top level */
+# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME          0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx));
+void ASN1_SCTX_free(ASN1_SCTX *p);
+const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p);
+const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p);
+unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p);
+void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data);
+void *ASN1_SCTX_get_app_data(ASN1_SCTX *p);
+
+const BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                        const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                              const char *hdr, const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+                     int ctype_nid, int econt_nid,
+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+const ASN1_ITEM *ASN1_ITEM_lookup(const char *name);
+const ASN1_ITEM *ASN1_ITEM_get(size_t i);
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 10 - 0
rambus_sec_lib/include/openssl/asn1_mac.h

@@ -0,0 +1,10 @@
+/*
+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#error "This file is obsolete; please update your software."

+ 256 - 0
rambus_sec_lib/include/openssl/asn1err.h

@@ -0,0 +1,256 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_ASN1ERR_H
+# define HEADER_ASN1ERR_H
+
+# include <openssl/symhacks.h>
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_ASN1_strings(void);
+
+/*
+ * ASN1 function codes.
+ */
+# define ASN1_F_A2D_ASN1_OBJECT                           100
+# define ASN1_F_A2I_ASN1_INTEGER                          102
+# define ASN1_F_A2I_ASN1_STRING                           103
+# define ASN1_F_APPEND_EXP                                176
+# define ASN1_F_ASN1_BIO_INIT                             113
+# define ASN1_F_ASN1_BIT_STRING_SET_BIT                   183
+# define ASN1_F_ASN1_CB                                   177
+# define ASN1_F_ASN1_CHECK_TLEN                           104
+# define ASN1_F_ASN1_COLLECT                              106
+# define ASN1_F_ASN1_D2I_EX_PRIMITIVE                     108
+# define ASN1_F_ASN1_D2I_FP                               109
+# define ASN1_F_ASN1_D2I_READ_BIO                         107
+# define ASN1_F_ASN1_DIGEST                               184
+# define ASN1_F_ASN1_DO_ADB                               110
+# define ASN1_F_ASN1_DO_LOCK                              233
+# define ASN1_F_ASN1_DUP                                  111
+# define ASN1_F_ASN1_ENC_SAVE                             115
+# define ASN1_F_ASN1_EX_C2I                               204
+# define ASN1_F_ASN1_FIND_END                             190
+# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ                  216
+# define ASN1_F_ASN1_GENERATE_V3                          178
+# define ASN1_F_ASN1_GET_INT64                            224
+# define ASN1_F_ASN1_GET_OBJECT                           114
+# define ASN1_F_ASN1_GET_UINT64                           225
+# define ASN1_F_ASN1_I2D_BIO                              116
+# define ASN1_F_ASN1_I2D_FP                               117
+# define ASN1_F_ASN1_ITEM_D2I_FP                          206
+# define ASN1_F_ASN1_ITEM_DUP                             191
+# define ASN1_F_ASN1_ITEM_EMBED_D2I                       120
+# define ASN1_F_ASN1_ITEM_EMBED_NEW                       121
+# define ASN1_F_ASN1_ITEM_EX_I2D                          144
+# define ASN1_F_ASN1_ITEM_FLAGS_I2D                       118
+# define ASN1_F_ASN1_ITEM_I2D_BIO                         192
+# define ASN1_F_ASN1_ITEM_I2D_FP                          193
+# define ASN1_F_ASN1_ITEM_PACK                            198
+# define ASN1_F_ASN1_ITEM_SIGN                            195
+# define ASN1_F_ASN1_ITEM_SIGN_CTX                        220
+# define ASN1_F_ASN1_ITEM_UNPACK                          199
+# define ASN1_F_ASN1_ITEM_VERIFY                          197
+# define ASN1_F_ASN1_MBSTRING_NCOPY                       122
+# define ASN1_F_ASN1_OBJECT_NEW                           123
+# define ASN1_F_ASN1_OUTPUT_DATA                          214
+# define ASN1_F_ASN1_PCTX_NEW                             205
+# define ASN1_F_ASN1_PRIMITIVE_NEW                        119
+# define ASN1_F_ASN1_SCTX_NEW                             221
+# define ASN1_F_ASN1_SIGN                                 128
+# define ASN1_F_ASN1_STR2TYPE                             179
+# define ASN1_F_ASN1_STRING_GET_INT64                     227
+# define ASN1_F_ASN1_STRING_GET_UINT64                    230
+# define ASN1_F_ASN1_STRING_SET                           186
+# define ASN1_F_ASN1_STRING_TABLE_ADD                     129
+# define ASN1_F_ASN1_STRING_TO_BN                         228
+# define ASN1_F_ASN1_STRING_TYPE_NEW                      130
+# define ASN1_F_ASN1_TEMPLATE_EX_D2I                      132
+# define ASN1_F_ASN1_TEMPLATE_NEW                         133
+# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I                   131
+# define ASN1_F_ASN1_TIME_ADJ                             217
+# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING             134
+# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING                 135
+# define ASN1_F_ASN1_UTCTIME_ADJ                          218
+# define ASN1_F_ASN1_VERIFY                               137
+# define ASN1_F_B64_READ_ASN1                             209
+# define ASN1_F_B64_WRITE_ASN1                            210
+# define ASN1_F_BIO_NEW_NDEF                              208
+# define ASN1_F_BITSTR_CB                                 180
+# define ASN1_F_BN_TO_ASN1_STRING                         229
+# define ASN1_F_C2I_ASN1_BIT_STRING                       189
+# define ASN1_F_C2I_ASN1_INTEGER                          194
+# define ASN1_F_C2I_ASN1_OBJECT                           196
+# define ASN1_F_C2I_IBUF                                  226
+# define ASN1_F_C2I_UINT64_INT                            101
+# define ASN1_F_COLLECT_DATA                              140
+# define ASN1_F_D2I_ASN1_OBJECT                           147
+# define ASN1_F_D2I_ASN1_UINTEGER                         150
+# define ASN1_F_D2I_AUTOPRIVATEKEY                        207
+# define ASN1_F_D2I_PRIVATEKEY                            154
+# define ASN1_F_D2I_PUBLICKEY                             155
+# define ASN1_F_DO_BUF                                    142
+# define ASN1_F_DO_CREATE                                 124
+# define ASN1_F_DO_DUMP                                   125
+# define ASN1_F_DO_TCREATE                                222
+# define ASN1_F_I2A_ASN1_OBJECT                           126
+# define ASN1_F_I2D_ASN1_BIO_STREAM                       211
+# define ASN1_F_I2D_ASN1_OBJECT                           143
+# define ASN1_F_I2D_DSA_PUBKEY                            161
+# define ASN1_F_I2D_EC_PUBKEY                             181
+# define ASN1_F_I2D_PRIVATEKEY                            163
+# define ASN1_F_I2D_PUBLICKEY                             164
+# define ASN1_F_I2D_RSA_PUBKEY                            165
+# define ASN1_F_LONG_C2I                                  166
+# define ASN1_F_NDEF_PREFIX                               127
+# define ASN1_F_NDEF_SUFFIX                               136
+# define ASN1_F_OID_MODULE_INIT                           174
+# define ASN1_F_PARSE_TAGGING                             182
+# define ASN1_F_PKCS5_PBE2_SET_IV                         167
+# define ASN1_F_PKCS5_PBE2_SET_SCRYPT                     231
+# define ASN1_F_PKCS5_PBE_SET                             202
+# define ASN1_F_PKCS5_PBE_SET0_ALGOR                      215
+# define ASN1_F_PKCS5_PBKDF2_SET                          219
+# define ASN1_F_PKCS5_SCRYPT_SET                          232
+# define ASN1_F_SMIME_READ_ASN1                           212
+# define ASN1_F_SMIME_TEXT                                213
+# define ASN1_F_STABLE_GET                                138
+# define ASN1_F_STBL_MODULE_INIT                          223
+# define ASN1_F_UINT32_C2I                                105
+# define ASN1_F_UINT32_NEW                                139
+# define ASN1_F_UINT64_C2I                                112
+# define ASN1_F_UINT64_NEW                                141
+# define ASN1_F_X509_CRL_ADD0_REVOKED                     169
+# define ASN1_F_X509_INFO_NEW                             170
+# define ASN1_F_X509_NAME_ENCODE                          203
+# define ASN1_F_X509_NAME_EX_D2I                          158
+# define ASN1_F_X509_NAME_EX_NEW                          171
+# define ASN1_F_X509_PKEY_NEW                             173
+
+/*
+ * ASN1 reason codes.
+ */
+# define ASN1_R_ADDING_OBJECT                             171
+# define ASN1_R_ASN1_PARSE_ERROR                          203
+# define ASN1_R_ASN1_SIG_PARSE_ERROR                      204
+# define ASN1_R_AUX_ERROR                                 100
+# define ASN1_R_BAD_OBJECT_HEADER                         102
+# define ASN1_R_BAD_TEMPLATE                              230
+# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH                 214
+# define ASN1_R_BN_LIB                                    105
+# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                   106
+# define ASN1_R_BUFFER_TOO_SMALL                          107
+# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER           108
+# define ASN1_R_CONTEXT_NOT_INITIALISED                   217
+# define ASN1_R_DATA_IS_WRONG                             109
+# define ASN1_R_DECODE_ERROR                              110
+# define ASN1_R_DEPTH_EXCEEDED                            174
+# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED         198
+# define ASN1_R_ENCODE_ERROR                              112
+# define ASN1_R_ERROR_GETTING_TIME                        173
+# define ASN1_R_ERROR_LOADING_SECTION                     172
+# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS               114
+# define ASN1_R_EXPECTING_AN_INTEGER                      115
+# define ASN1_R_EXPECTING_AN_OBJECT                       116
+# define ASN1_R_EXPLICIT_LENGTH_MISMATCH                  119
+# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED              120
+# define ASN1_R_FIELD_MISSING                             121
+# define ASN1_R_FIRST_NUM_TOO_LARGE                       122
+# define ASN1_R_HEADER_TOO_LONG                           123
+# define ASN1_R_ILLEGAL_BITSTRING_FORMAT                  175
+# define ASN1_R_ILLEGAL_BOOLEAN                           176
+# define ASN1_R_ILLEGAL_CHARACTERS                        124
+# define ASN1_R_ILLEGAL_FORMAT                            177
+# define ASN1_R_ILLEGAL_HEX                               178
+# define ASN1_R_ILLEGAL_IMPLICIT_TAG                      179
+# define ASN1_R_ILLEGAL_INTEGER                           180
+# define ASN1_R_ILLEGAL_NEGATIVE_VALUE                    226
+# define ASN1_R_ILLEGAL_NESTED_TAGGING                    181
+# define ASN1_R_ILLEGAL_NULL                              125
+# define ASN1_R_ILLEGAL_NULL_VALUE                        182
+# define ASN1_R_ILLEGAL_OBJECT                            183
+# define ASN1_R_ILLEGAL_OPTIONAL_ANY                      126
+# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE          170
+# define ASN1_R_ILLEGAL_PADDING                           221
+# define ASN1_R_ILLEGAL_TAGGED_ANY                        127
+# define ASN1_R_ILLEGAL_TIME_VALUE                        184
+# define ASN1_R_ILLEGAL_ZERO_CONTENT                      222
+# define ASN1_R_INTEGER_NOT_ASCII_FORMAT                  185
+# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG                128
+# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT              220
+# define ASN1_R_INVALID_BMPSTRING_LENGTH                  129
+# define ASN1_R_INVALID_DIGIT                             130
+# define ASN1_R_INVALID_MIME_TYPE                         205
+# define ASN1_R_INVALID_MODIFIER                          186
+# define ASN1_R_INVALID_NUMBER                            187
+# define ASN1_R_INVALID_OBJECT_ENCODING                   216
+# define ASN1_R_INVALID_SCRYPT_PARAMETERS                 227
+# define ASN1_R_INVALID_SEPARATOR                         131
+# define ASN1_R_INVALID_STRING_TABLE_VALUE                218
+# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH            133
+# define ASN1_R_INVALID_UTF8STRING                        134
+# define ASN1_R_INVALID_VALUE                             219
+# define ASN1_R_LIST_ERROR                                188
+# define ASN1_R_MIME_NO_CONTENT_TYPE                      206
+# define ASN1_R_MIME_PARSE_ERROR                          207
+# define ASN1_R_MIME_SIG_PARSE_ERROR                      208
+# define ASN1_R_MISSING_EOC                               137
+# define ASN1_R_MISSING_SECOND_NUMBER                     138
+# define ASN1_R_MISSING_VALUE                             189
+# define ASN1_R_MSTRING_NOT_UNIVERSAL                     139
+# define ASN1_R_MSTRING_WRONG_TAG                         140
+# define ASN1_R_NESTED_ASN1_STRING                        197
+# define ASN1_R_NESTED_TOO_DEEP                           201
+# define ASN1_R_NON_HEX_CHARACTERS                        141
+# define ASN1_R_NOT_ASCII_FORMAT                          190
+# define ASN1_R_NOT_ENOUGH_DATA                           142
+# define ASN1_R_NO_CONTENT_TYPE                           209
+# define ASN1_R_NO_MATCHING_CHOICE_TYPE                   143
+# define ASN1_R_NO_MULTIPART_BODY_FAILURE                 210
+# define ASN1_R_NO_MULTIPART_BOUNDARY                     211
+# define ASN1_R_NO_SIG_CONTENT_TYPE                       212
+# define ASN1_R_NULL_IS_WRONG_LENGTH                      144
+# define ASN1_R_OBJECT_NOT_ASCII_FORMAT                   191
+# define ASN1_R_ODD_NUMBER_OF_CHARS                       145
+# define ASN1_R_SECOND_NUMBER_TOO_LARGE                   147
+# define ASN1_R_SEQUENCE_LENGTH_MISMATCH                  148
+# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED                  149
+# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG              192
+# define ASN1_R_SHORT_LINE                                150
+# define ASN1_R_SIG_INVALID_MIME_TYPE                     213
+# define ASN1_R_STREAMING_NOT_SUPPORTED                   202
+# define ASN1_R_STRING_TOO_LONG                           151
+# define ASN1_R_STRING_TOO_SHORT                          152
+# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+# define ASN1_R_TIME_NOT_ASCII_FORMAT                     193
+# define ASN1_R_TOO_LARGE                                 223
+# define ASN1_R_TOO_LONG                                  155
+# define ASN1_R_TOO_SMALL                                 224
+# define ASN1_R_TYPE_NOT_CONSTRUCTED                      156
+# define ASN1_R_TYPE_NOT_PRIMITIVE                        195
+# define ASN1_R_UNEXPECTED_EOC                            159
+# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH           215
+# define ASN1_R_UNKNOWN_FORMAT                            160
+# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM          161
+# define ASN1_R_UNKNOWN_OBJECT_TYPE                       162
+# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE                   163
+# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM               199
+# define ASN1_R_UNKNOWN_TAG                               194
+# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE           164
+# define ASN1_R_UNSUPPORTED_CIPHER                        228
+# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE               167
+# define ASN1_R_UNSUPPORTED_TYPE                          196
+# define ASN1_R_WRONG_INTEGER_TYPE                        225
+# define ASN1_R_WRONG_PUBLIC_KEY_TYPE                     200
+# define ASN1_R_WRONG_TAG                                 168
+
+#endif

+ 945 - 0
rambus_sec_lib/include/openssl/asn1t.h

@@ -0,0 +1,945 @@
+/*
+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_ASN1T_H
+# define HEADER_ASN1T_H
+
+# include <stddef.h>
+# include <openssl/e_os2.h>
+# include <openssl/asn1.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        const ASN1_ITEM itname##_it = {
+
+#  define static_ASN1_ITEM_start(itname) \
+        static const ASN1_ITEM itname##_it = {
+
+#  define ASN1_ITEM_end(itname)                 \
+                };
+
+# else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)()))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        const ASN1_ITEM * itname##_it(void) \
+        { \
+                static const ASN1_ITEM local_it = {
+
+#  define static_ASN1_ITEM_start(itname) \
+        static ASN1_ITEM_start(itname)
+
+#  define ASN1_ITEM_end(itname) \
+                }; \
+        return &local_it; \
+        }
+
+# endif
+
+/* Macros to aid ASN1 template writing */
+
+# define ASN1_ITEM_TEMPLATE(tname) \
+        static const ASN1_TEMPLATE tname##_item_tt
+
+# define ASN1_ITEM_TEMPLATE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_PRIMITIVE,\
+                -1,\
+                &tname##_item_tt,\
+                0,\
+                NULL,\
+                0,\
+                #tname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_ITEM_TEMPLATE_END(tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_PRIMITIVE,\
+                -1,\
+                &tname##_item_tt,\
+                0,\
+                NULL,\
+                0,\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+/* This is a ASN1 type which just embeds a template */
+
+/*-
+ * This pair helps declare a SEQUENCE. We can do:
+ *
+ *      ASN1_SEQUENCE(stname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END(stname)
+ *
+ *      This will produce an ASN1_ITEM called stname_it
+ *      for a structure called stname.
+ *
+ *      If you want the same structure but a different
+ *      name then use:
+ *
+ *      ASN1_SEQUENCE(itname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *      This will create an item called itname_it using
+ *      a structure called stname.
+ */
+
+# define ASN1_SEQUENCE(tname) \
+        static const ASN1_TEMPLATE tname##_seq_tt[]
+
+# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname)
+
+# define ASN1_SEQUENCE_END_name(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+# define static_ASN1_SEQUENCE_END_name(stname, tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE(tname) \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
+        ASN1_SEQUENCE_cb(tname, cb)
+
+# define ASN1_SEQUENCE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_BROKEN_SEQUENCE(tname) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_ref(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_enc(tname, enc, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(tname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_NDEF_SEQUENCE_END(tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(tname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+# define static_ASN1_BROKEN_SEQUENCE_END(stname) \
+        static_ASN1_SEQUENCE_END_ref(stname, stname)
+
+# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_ref(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_SEQUENCE_END_ref(stname, tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/*-
+ * This pair helps declare a CHOICE type. We can do:
+ *
+ *      ASN1_CHOICE(chname) = {
+ *              ... CHOICE options ...
+ *      ASN1_CHOICE_END(chname)
+ *
+ *      This will produce an ASN1_ITEM called chname_it
+ *      for a structure called chname. The structure
+ *      definition must look like this:
+ *      typedef struct {
+ *              int type;
+ *              union {
+ *                      ASN1_SOMETHING *opt1;
+ *                      ASN1_SOMEOTHER *opt2;
+ *              } value;
+ *      } chname;
+ *
+ *      the name of the selector must be 'type'.
+ *      to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+# define ASN1_CHOICE(tname) \
+        static const ASN1_TEMPLATE tname##_ch_tt[]
+
+# define ASN1_CHOICE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_CHOICE(tname)
+
+# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname)
+
+# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define ASN1_CHOICE_END_selector(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_CHOICE_END_cb(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+        (flags), (tag), 0,\
+        #name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+        (flags), (tag), offsetof(stname, field),\
+        #field, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+# define ASN1_IMP_EX(stname, field, type, tag, ex) \
+         ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type)
+
+# define ASN1_EXP_EX(stname, field, type, tag, ex) \
+         ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+# else
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+# endif
+/* Plain simple type */
+# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+/* Embedded simple type */
+# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type)
+
+/* OPTIONAL simple type */
+# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED)
+
+/* Same as above but EXPLICIT */
+
+# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED)
+# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED)
+
+/* SEQUENCE OF type */
+# define ASN1_SEQUENCE_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+# define ASN1_SET_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+# define ASN1_SET_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+# define ASN1_IMP_SET_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_EXP_SET_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT using indefinite length constructed form */
+# define ASN1_NDEF_EXP(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+# define ASN1_ADB(name) \
+        static const ASN1_ADB_TABLE name##_adbtbl[]
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#  define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
+        ;\
+        static const ASN1_ADB name##_adb = {\
+                flags,\
+                offsetof(name, field),\
+                adb_cb,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+        }
+
+# else
+
+#  define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
+        ;\
+        static const ASN1_ITEM *name##_adb(void) \
+        { \
+        static const ASN1_ADB internal_adb = \
+                {\
+                flags,\
+                offsetof(name, field),\
+                adb_cb,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+                }; \
+                return (const ASN1_ITEM *) &internal_adb; \
+        } \
+        void dummy_function(void)
+
+# endif
+
+# define ADB_ENTRY(val, template) {val, template}
+
+# define ASN1_ADB_TEMPLATE(name) \
+        static const ASN1_TEMPLATE name##_tt
+
+/*
+ * This is the ASN1 template structure that defines a wrapper round the
+ * actual type. It determines the actual position of the field in the value
+ * structure, various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+    unsigned long flags;        /* Various flags */
+    long tag;                   /* tag, not used if no tagging */
+    unsigned long offset;       /* Offset of this field in structure */
+    const char *field_name;     /* Field name */
+    ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+# define ASN1_TEMPLATE_item(t) (t->item_ptr)
+# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+    unsigned long flags;        /* Various flags */
+    unsigned long offset;       /* Offset of selector field */
+    int (*adb_cb)(long *psel);  /* Application callback */
+    const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
+    long tblcount;              /* Number of entries in tbl */
+    const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
+    const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+    long value;                 /* NID for an object or value for an int */
+    const ASN1_TEMPLATE tt;     /* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+# define ASN1_TFLG_OPTIONAL      (0x1)
+
+/* Field is a SET OF */
+# define ASN1_TFLG_SET_OF        (0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+# define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)
+
+/*
+ * Special case: this refers to a SET OF that will be sorted into DER order
+ * when encoded *and* the corresponding STACK will be modified to match the
+ * new order.
+ */
+# define ASN1_TFLG_SET_ORDER     (0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+# define ASN1_TFLG_SK_MASK       (0x3 << 1)
+
+/*
+ * These flags mean the tag should be taken from the tag field. If EXPLICIT
+ * then the underlying type is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+# define ASN1_TFLG_IMPTAG        (0x1 << 3)
+
+/* EXPLICIT tagging, inner tag from underlying type */
+# define ASN1_TFLG_EXPTAG        (0x2 << 3)
+
+# define ASN1_TFLG_TAG_MASK      (0x3 << 3)
+
+/* context specific IMPLICIT */
+# define ASN1_TFLG_IMPLICIT      (ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT)
+
+/* context specific EXPLICIT */
+# define ASN1_TFLG_EXPLICIT      (ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT)
+
+/*
+ * If tagging is in force these determine the type of tag to use. Otherwise
+ * the tag is determined by the underlying type. These values reflect the
+ * actual octet format.
+ */
+
+/* Universal tag */
+# define ASN1_TFLG_UNIVERSAL     (0x0<<6)
+/* Application tag */
+# define ASN1_TFLG_APPLICATION   (0x1<<6)
+/* Context specific tag */
+# define ASN1_TFLG_CONTEXT       (0x2<<6)
+/* Private tag */
+# define ASN1_TFLG_PRIVATE       (0x3<<6)
+
+# define ASN1_TFLG_TAG_CLASS     (0x3<<6)
+
+/*
+ * These are for ANY DEFINED BY type. In this case the 'item' field points to
+ * an ASN1_ADB structure which contains a table of values to decode the
+ * relevant type
+ */
+
+# define ASN1_TFLG_ADB_MASK      (0x3<<8)
+
+# define ASN1_TFLG_ADB_OID       (0x1<<8)
+
+# define ASN1_TFLG_ADB_INT       (0x1<<9)
+
+/*
+ * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
+ * indefinite length constructed encoding to be used if required.
+ */
+
+# define ASN1_TFLG_NDEF          (0x1<<11)
+
+/* Field is embedded and not a pointer */
+# define ASN1_TFLG_EMBED         (0x1 << 12)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+    char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
+                                 * or extern */
+    long utype;                 /* underlying type */
+    const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
+                                     * the contents */
+    long tcount;                /* Number of templates if SEQUENCE or CHOICE */
+    const void *funcs;          /* functions that handle this type */
+    long size;                  /* Structure size (usually) */
+    const char *sname;          /* Structure name */
+};
+
+/*-
+ * These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+# define ASN1_ITYPE_PRIMITIVE            0x0
+
+# define ASN1_ITYPE_SEQUENCE             0x1
+
+# define ASN1_ITYPE_CHOICE               0x2
+
+# define ASN1_ITYPE_EXTERN               0x4
+
+# define ASN1_ITYPE_MSTRING              0x5
+
+# define ASN1_ITYPE_NDEF_SEQUENCE        0x6
+
+/*
+ * Cache for ASN1 tag and length, so we don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st {
+    char valid;                 /* Values below are valid */
+    int ret;                    /* return value */
+    long plen;                  /* length */
+    int ptag;                   /* class value */
+    int pclass;                 /* class value */
+    int hdrlen;                 /* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                        const ASN1_ITEM *it, int tag, int aclass, char opt,
+                        ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                        const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
+                               int indent, const char *fname,
+                               const ASN1_PCTX *pctx);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
+                               int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
+                               int len, int utype, char *free_cont,
+                               const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
+                                 const ASN1_ITEM *it, int indent,
+                                 const ASN1_PCTX *pctx);
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+    void *app_data;
+    ASN1_ex_new_func *asn1_ex_new;
+    ASN1_ex_free_func *asn1_ex_free;
+    ASN1_ex_free_func *asn1_ex_clear;
+    ASN1_ex_d2i *asn1_ex_d2i;
+    ASN1_ex_i2d *asn1_ex_i2d;
+    ASN1_ex_print_func *asn1_ex_print;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+    void *app_data;
+    unsigned long flags;
+    ASN1_ex_new_func *prim_new;
+    ASN1_ex_free_func *prim_free;
+    ASN1_ex_free_func *prim_clear;
+    ASN1_primitive_c2i *prim_c2i;
+    ASN1_primitive_i2c *prim_i2c;
+    ASN1_primitive_print *prim_print;
+} ASN1_PRIMITIVE_FUNCS;
+
+/*
+ * This is the ASN1_AUX structure: it handles various miscellaneous
+ * requirements. For example the use of reference counts and an informational
+ * callback. The "informational callback" is called at various points during
+ * the ASN1 encoding and decoding. It can be used to provide minor
+ * customisation of the structures used. This is most useful where the
+ * supplied routines *almost* do the right thing but need some extra help at
+ * a few points. If the callback returns zero then it is assumed a fatal
+ * error has occurred and the main operation should be abandoned. If major
+ * changes in the default behaviour are required then an external type is
+ * more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+                        void *exarg);
+
+typedef struct ASN1_AUX_st {
+    void *app_data;
+    int flags;
+    int ref_offset;             /* Offset of reference value */
+    int ref_lock;               /* Lock type to use */
+    ASN1_aux_cb *asn1_cb;
+    int enc_offset;             /* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+    BIO *out;
+    int indent;
+    const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+    /* BIO to stream through */
+    BIO *out;
+    /* BIO with filters appended */
+    BIO *ndef_bio;
+    /* Streaming I/O boundary */
+    unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+# define ASN1_AFLG_REFCOUNT      1
+/* Save the encoding of structure (useful for signatures) */
+# define ASN1_AFLG_ENCODING      2
+/* The Sequence length is invalid */
+# define ASN1_AFLG_BROKEN        4
+
+/* operation values for asn1_cb */
+
+# define ASN1_OP_NEW_PRE         0
+# define ASN1_OP_NEW_POST        1
+# define ASN1_OP_FREE_PRE        2
+# define ASN1_OP_FREE_POST       3
+# define ASN1_OP_D2I_PRE         4
+# define ASN1_OP_D2I_POST        5
+# define ASN1_OP_I2D_PRE         6
+# define ASN1_OP_I2D_POST        7
+# define ASN1_OP_PRINT_PRE       8
+# define ASN1_OP_PRINT_POST      9
+# define ASN1_OP_STREAM_PRE      10
+# define ASN1_OP_STREAM_POST     11
+# define ASN1_OP_DETACHED_PRE    12
+# define ASN1_OP_DETACHED_POST   13
+
+/* Macro to implement a primitive type */
+# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+                                ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+                                ASN1_ITEM_end(itname)
+
+# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+        ASN1_ITEM_start(sname) \
+                ASN1_ITYPE_EXTERN, \
+                tag, \
+                NULL, \
+                0, \
+                &fptrs, \
+                0, \
+                #sname \
+        ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+                        IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+        pre stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        pre void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+        stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+        }
+
+# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \
+        static stname *d2i_##stname(stname **a, \
+                                   const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \
+                                               ASN1_ITEM_rptr(stname)); \
+        } \
+        static int i2d_##stname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, \
+                                     ASN1_ITEM_rptr(stname)); \
+        }
+
+/*
+ * This includes evil casts to remove const: they will go away when full ASN1
+ * constification is done.
+ */
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(const stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+        stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+        IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                                const ASN1_PCTX *pctx) \
+        { \
+                return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+                        ASN1_ITEM_rptr(itname), pctx); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(INT32)
+DECLARE_ASN1_ITEM(ZINT32)
+DECLARE_ASN1_ITEM(UINT32)
+DECLARE_ASN1_ITEM(ZUINT32)
+DECLARE_ASN1_ITEM(INT64)
+DECLARE_ASN1_ITEM(ZINT64)
+DECLARE_ASN1_ITEM(UINT64)
+DECLARE_ASN1_ITEM(ZUINT64)
+
+# if OPENSSL_API_COMPAT < 0x10200000L
+/*
+ * LONG and ZLONG are strongly discouraged for use as stored data, as the
+ * underlying C type (long) differs in size depending on the architecture.
+ * They are designed with 32-bit longs in mind.
+ */
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+# endif
+
+DEFINE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                     const ASN1_ITEM *it, int tag, int aclass, char opt,
+                     ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                     const ASN1_ITEM *it, int tag, int aclass);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif

+ 76 - 0
rambus_sec_lib/include/openssl/async.h

@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>
+
+#ifndef HEADER_ASYNC_H
+# define HEADER_ASYNC_H
+
+#if defined(_WIN32)
+# if defined(BASETYPES) || defined(_WINDEF_H)
+/* application has to include <windows.h> to use this */
+#define OSSL_ASYNC_FD       HANDLE
+#define OSSL_BAD_ASYNC_FD   INVALID_HANDLE_VALUE
+# endif
+#else
+#define OSSL_ASYNC_FD       int
+#define OSSL_BAD_ASYNC_FD   -1
+#endif
+# include <openssl/asyncerr.h>
+
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef struct async_job_st ASYNC_JOB;
+typedef struct async_wait_ctx_st ASYNC_WAIT_CTX;
+
+#define ASYNC_ERR      0
+#define ASYNC_NO_JOBS  1
+#define ASYNC_PAUSE    2
+#define ASYNC_FINISH   3
+
+int ASYNC_init_thread(size_t max_size, size_t init_size);
+void ASYNC_cleanup_thread(void);
+
+#ifdef OSSL_ASYNC_FD
+ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void);
+void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx);
+int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                               OSSL_ASYNC_FD fd,
+                               void *custom_data,
+                               void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
+                                               OSSL_ASYNC_FD, void *));
+int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                        OSSL_ASYNC_FD *fd, void **custom_data);
+int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
+                               size_t *numfds);
+int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
+                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
+                                   size_t *numdelfds);
+int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key);
+#endif
+
+int ASYNC_is_capable(void);
+
+int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret,
+                    int (*func)(void *), void *args, size_t size);
+int ASYNC_pause_job(void);
+
+ASYNC_JOB *ASYNC_get_current_job(void);
+ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job);
+void ASYNC_block_pause(void);
+void ASYNC_unblock_pause(void);
+
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 42 - 0
rambus_sec_lib/include/openssl/asyncerr.h

@@ -0,0 +1,42 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_ASYNCERR_H
+# define HEADER_ASYNCERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_ASYNC_strings(void);
+
+/*
+ * ASYNC function codes.
+ */
+# define ASYNC_F_ASYNC_CTX_NEW                            100
+# define ASYNC_F_ASYNC_INIT_THREAD                        101
+# define ASYNC_F_ASYNC_JOB_NEW                            102
+# define ASYNC_F_ASYNC_PAUSE_JOB                          103
+# define ASYNC_F_ASYNC_START_FUNC                         104
+# define ASYNC_F_ASYNC_START_JOB                          105
+# define ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD               106
+
+/*
+ * ASYNC reason codes.
+ */
+# define ASYNC_R_FAILED_TO_SET_POOL                       101
+# define ASYNC_R_FAILED_TO_SWAP_CONTEXT                   102
+# define ASYNC_R_INIT_FAILED                              105
+# define ASYNC_R_INVALID_POOL_SIZE                        103
+
+#endif

+ 801 - 0
rambus_sec_lib/include/openssl/bio.h

@@ -0,0 +1,801 @@
+/*
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BIO_H
+# define HEADER_BIO_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+
+# include <openssl/crypto.h>
+# include <openssl/bioerr.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* There are the classes of BIOs */
+# define BIO_TYPE_DESCRIPTOR     0x0100 /* socket, fd, connect or accept */
+# define BIO_TYPE_FILTER         0x0200
+# define BIO_TYPE_SOURCE_SINK    0x0400
+
+/* These are the 'types' of BIOs */
+# define BIO_TYPE_NONE             0
+# define BIO_TYPE_MEM            ( 1|BIO_TYPE_SOURCE_SINK)
+# define BIO_TYPE_FILE           ( 2|BIO_TYPE_SOURCE_SINK)
+
+# define BIO_TYPE_FD             ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_SOCKET         ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_NULL           ( 6|BIO_TYPE_SOURCE_SINK)
+# define BIO_TYPE_SSL            ( 7|BIO_TYPE_FILTER)
+# define BIO_TYPE_MD             ( 8|BIO_TYPE_FILTER)
+# define BIO_TYPE_BUFFER         ( 9|BIO_TYPE_FILTER)
+# define BIO_TYPE_CIPHER         (10|BIO_TYPE_FILTER)
+# define BIO_TYPE_BASE64         (11|BIO_TYPE_FILTER)
+# define BIO_TYPE_CONNECT        (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_ACCEPT         (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+
+# define BIO_TYPE_NBIO_TEST      (16|BIO_TYPE_FILTER)/* server proxy BIO */
+# define BIO_TYPE_NULL_FILTER    (17|BIO_TYPE_FILTER)
+# define BIO_TYPE_BIO            (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */
+# define BIO_TYPE_LINEBUFFER     (20|BIO_TYPE_FILTER)
+# define BIO_TYPE_DGRAM          (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_ASN1           (22|BIO_TYPE_FILTER)
+# define BIO_TYPE_COMP           (23|BIO_TYPE_FILTER)
+# ifndef OPENSSL_NO_SCTP
+#  define BIO_TYPE_DGRAM_SCTP    (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# endif
+
+#define BIO_TYPE_START           128
+
+/*
+ * BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ */
+# define BIO_NOCLOSE             0x00
+# define BIO_CLOSE               0x01
+
+/*
+ * These are used in the following macros and are passed to BIO_ctrl()
+ */
+# define BIO_CTRL_RESET          1/* opt - rewind/zero etc */
+# define BIO_CTRL_EOF            2/* opt - are we at the eof */
+# define BIO_CTRL_INFO           3/* opt - extra tit-bits */
+# define BIO_CTRL_SET            4/* man - set the 'IO' type */
+# define BIO_CTRL_GET            5/* man - get the 'IO' type */
+# define BIO_CTRL_PUSH           6/* opt - internal, used to signify change */
+# define BIO_CTRL_POP            7/* opt - internal, used to signify change */
+# define BIO_CTRL_GET_CLOSE      8/* man - set the 'close' on free */
+# define BIO_CTRL_SET_CLOSE      9/* man - set the 'close' on free */
+# define BIO_CTRL_PENDING        10/* opt - is their more data buffered */
+# define BIO_CTRL_FLUSH          11/* opt - 'flush' buffered output */
+# define BIO_CTRL_DUP            12/* man - extra stuff for 'duped' BIO */
+# define BIO_CTRL_WPENDING       13/* opt - number of bytes still to write */
+# define BIO_CTRL_SET_CALLBACK   14/* opt - set callback function */
+# define BIO_CTRL_GET_CALLBACK   15/* opt - set callback function */
+
+# define BIO_CTRL_PEEK           29/* BIO_f_buffer special */
+# define BIO_CTRL_SET_FILENAME   30/* BIO_s_file special */
+
+/* dgram BIO stuff */
+# define BIO_CTRL_DGRAM_CONNECT       31/* BIO dgram special */
+# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected
+                                         * socket to be passed in */
+# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */
+# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */
+
+# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */
+
+/* #ifdef IP_MTU_DISCOVER */
+# define BIO_CTRL_DGRAM_MTU_DISCOVER       39/* set DF bit on egress packets */
+/* #endif */
+
+# define BIO_CTRL_DGRAM_QUERY_MTU          40/* as kernel for current MTU */
+# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
+# define BIO_CTRL_DGRAM_GET_MTU            41/* get cached value for MTU */
+# define BIO_CTRL_DGRAM_SET_MTU            42/* set cached value for MTU.
+                                              * want to use this if asking
+                                              * the kernel fails */
+
+# define BIO_CTRL_DGRAM_MTU_EXCEEDED       43/* check whether the MTU was
+                                              * exceed in the previous write
+                                              * operation */
+
+# define BIO_CTRL_DGRAM_GET_PEER           46
+# define BIO_CTRL_DGRAM_SET_PEER           44/* Destination for the data */
+
+# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45/* Next DTLS handshake timeout
+                                              * to adjust socket timeouts */
+# define BIO_CTRL_DGRAM_SET_DONT_FRAG      48
+
+# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49
+
+/* Deliberately outside of OPENSSL_NO_SCTP - used in bss_dgram.c */
+#  define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE    50
+# ifndef OPENSSL_NO_SCTP
+/* SCTP stuff */
+#  define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY                51
+#  define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY               52
+#  define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD               53
+#  define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO         60
+#  define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO         61
+#  define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO         62
+#  define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO         63
+#  define BIO_CTRL_DGRAM_SCTP_GET_PRINFO                  64
+#  define BIO_CTRL_DGRAM_SCTP_SET_PRINFO                  65
+#  define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN               70
+# endif
+
+# define BIO_CTRL_DGRAM_SET_PEEK_MODE      71
+
+/* modifiers */
+# define BIO_FP_READ             0x02
+# define BIO_FP_WRITE            0x04
+# define BIO_FP_APPEND           0x08
+# define BIO_FP_TEXT             0x10
+
+# define BIO_FLAGS_READ          0x01
+# define BIO_FLAGS_WRITE         0x02
+# define BIO_FLAGS_IO_SPECIAL    0x04
+# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+# define BIO_FLAGS_SHOULD_RETRY  0x08
+# ifndef BIO_FLAGS_UPLINK
+/*
+ * "UPLINK" flag denotes file descriptors provided by application. It
+ * defaults to 0, as most platforms don't require UPLINK interface.
+ */
+#  define BIO_FLAGS_UPLINK        0
+# endif
+
+# define BIO_FLAGS_BASE64_NO_NL  0x100
+
+/*
+ * This is used with memory BIOs:
+ * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way;
+ * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset.
+ */
+# define BIO_FLAGS_MEM_RDONLY    0x200
+# define BIO_FLAGS_NONCLEAR_RST  0x400
+# define BIO_FLAGS_IN_EOF        0x800
+
+typedef union bio_addr_st BIO_ADDR;
+typedef struct bio_addrinfo_st BIO_ADDRINFO;
+
+int BIO_get_new_index(void);
+void BIO_set_flags(BIO *b, int flags);
+int BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+# define BIO_set_retry_special(b) \
+                BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_read(b) \
+                BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_write(b) \
+                BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+# define BIO_clear_retry_flags(b) \
+                BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_get_retry_flags(b) \
+                BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+# define BIO_should_read(a)              BIO_test_flags(a, BIO_FLAGS_READ)
+# define BIO_should_write(a)             BIO_test_flags(a, BIO_FLAGS_WRITE)
+# define BIO_should_io_special(a)        BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+# define BIO_retry_type(a)               BIO_test_flags(a, BIO_FLAGS_RWS)
+# define BIO_should_retry(a)             BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/*
+ * The next three are used in conjunction with the BIO_should_io_special()
+ * condition.  After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int
+ * *reason); will walk the BIO stack and return the 'reason' for the special
+ * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return
+ * the code.
+ */
+/*
+ * Returned from the SSL bio when the certificate retrieval code had an error
+ */
+# define BIO_RR_SSL_X509_LOOKUP          0x01
+/* Returned from the connect BIO when a connect would have blocked */
+# define BIO_RR_CONNECT                  0x02
+/* Returned from the accept BIO when an accept would have blocked */
+# define BIO_RR_ACCEPT                   0x03
+
+/* These are passed by the BIO callback */
+# define BIO_CB_FREE     0x01
+# define BIO_CB_READ     0x02
+# define BIO_CB_WRITE    0x03
+# define BIO_CB_PUTS     0x04
+# define BIO_CB_GETS     0x05
+# define BIO_CB_CTRL     0x06
+
+/*
+ * The callback is called before and after the underling operation, The
+ * BIO_CB_RETURN flag indicates if it is after the call
+ */
+# define BIO_CB_RETURN   0x80
+# define BIO_CB_return(a) ((a)|BIO_CB_RETURN)
+# define BIO_cb_pre(a)   (!((a)&BIO_CB_RETURN))
+# define BIO_cb_post(a)  ((a)&BIO_CB_RETURN)
+
+typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi,
+                                long argl, long ret);
+typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp,
+                                   size_t len, int argi,
+                                   long argl, int ret, size_t *processed);
+BIO_callback_fn BIO_get_callback(const BIO *b);
+void BIO_set_callback(BIO *b, BIO_callback_fn callback);
+
+BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b);
+void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback);
+
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+typedef struct bio_method_st BIO_METHOD;
+
+const char *BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef int BIO_info_cb(BIO *, int, int);
+typedef BIO_info_cb bio_info_cb;  /* backward compatibility */
+
+DEFINE_STACK_OF(BIO)
+
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen,
+                          void *parg);
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP parameter structs */
+struct bio_dgram_sctp_sndinfo {
+    uint16_t snd_sid;
+    uint16_t snd_flags;
+    uint32_t snd_ppid;
+    uint32_t snd_context;
+};
+
+struct bio_dgram_sctp_rcvinfo {
+    uint16_t rcv_sid;
+    uint16_t rcv_ssn;
+    uint16_t rcv_flags;
+    uint32_t rcv_ppid;
+    uint32_t rcv_tsn;
+    uint32_t rcv_cumtsn;
+    uint32_t rcv_context;
+};
+
+struct bio_dgram_sctp_prinfo {
+    uint16_t pr_policy;
+    uint32_t pr_value;
+};
+# endif
+
+/*
+ * #define BIO_CONN_get_param_hostname BIO_ctrl
+ */
+
+# define BIO_C_SET_CONNECT                       100
+# define BIO_C_DO_STATE_MACHINE                  101
+# define BIO_C_SET_NBIO                          102
+/* # define BIO_C_SET_PROXY_PARAM                   103 */
+# define BIO_C_SET_FD                            104
+# define BIO_C_GET_FD                            105
+# define BIO_C_SET_FILE_PTR                      106
+# define BIO_C_GET_FILE_PTR                      107
+# define BIO_C_SET_FILENAME                      108
+# define BIO_C_SET_SSL                           109
+# define BIO_C_GET_SSL                           110
+# define BIO_C_SET_MD                            111
+# define BIO_C_GET_MD                            112
+# define BIO_C_GET_CIPHER_STATUS                 113
+# define BIO_C_SET_BUF_MEM                       114
+# define BIO_C_GET_BUF_MEM_PTR                   115
+# define BIO_C_GET_BUFF_NUM_LINES                116
+# define BIO_C_SET_BUFF_SIZE                     117
+# define BIO_C_SET_ACCEPT                        118
+# define BIO_C_SSL_MODE                          119
+# define BIO_C_GET_MD_CTX                        120
+/* # define BIO_C_GET_PROXY_PARAM                   121 */
+# define BIO_C_SET_BUFF_READ_DATA                122/* data to read first */
+# define BIO_C_GET_CONNECT                       123
+# define BIO_C_GET_ACCEPT                        124
+# define BIO_C_SET_SSL_RENEGOTIATE_BYTES         125
+# define BIO_C_GET_SSL_NUM_RENEGOTIATES          126
+# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT       127
+# define BIO_C_FILE_SEEK                         128
+# define BIO_C_GET_CIPHER_CTX                    129
+# define BIO_C_SET_BUF_MEM_EOF_RETURN            130/* return end of input
+                                                     * value */
+# define BIO_C_SET_BIND_MODE                     131
+# define BIO_C_GET_BIND_MODE                     132
+# define BIO_C_FILE_TELL                         133
+# define BIO_C_GET_SOCKS                         134
+# define BIO_C_SET_SOCKS                         135
+
+# define BIO_C_SET_WRITE_BUF_SIZE                136/* for BIO_s_bio */
+# define BIO_C_GET_WRITE_BUF_SIZE                137
+# define BIO_C_MAKE_BIO_PAIR                     138
+# define BIO_C_DESTROY_BIO_PAIR                  139
+# define BIO_C_GET_WRITE_GUARANTEE               140
+# define BIO_C_GET_READ_REQUEST                  141
+# define BIO_C_SHUTDOWN_WR                       142
+# define BIO_C_NREAD0                            143
+# define BIO_C_NREAD                             144
+# define BIO_C_NWRITE0                           145
+# define BIO_C_NWRITE                            146
+# define BIO_C_RESET_READ_REQUEST                147
+# define BIO_C_SET_MD_CTX                        148
+
+# define BIO_C_SET_PREFIX                        149
+# define BIO_C_GET_PREFIX                        150
+# define BIO_C_SET_SUFFIX                        151
+# define BIO_C_GET_SUFFIX                        152
+
+# define BIO_C_SET_EX_ARG                        153
+# define BIO_C_GET_EX_ARG                        154
+
+# define BIO_C_SET_CONNECT_MODE                  155
+
+# define BIO_set_app_data(s,arg)         BIO_set_ex_data(s,0,arg)
+# define BIO_get_app_data(s)             BIO_get_ex_data(s,0)
+
+# define BIO_set_nbio(b,n)             BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+# ifndef OPENSSL_NO_SOCK
+/* IP families we support, for BIO_s_connect() and BIO_s_accept() */
+/* Note: the underlying operating system may not support some of them */
+#  define BIO_FAMILY_IPV4                         4
+#  define BIO_FAMILY_IPV6                         6
+#  define BIO_FAMILY_IPANY                        256
+
+/* BIO_s_connect() */
+#  define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0, \
+                                                 (char *)(name))
+#  define BIO_set_conn_port(b,port)     BIO_ctrl(b,BIO_C_SET_CONNECT,1, \
+                                                 (char *)(port))
+#  define BIO_set_conn_address(b,addr)  BIO_ctrl(b,BIO_C_SET_CONNECT,2, \
+                                                 (char *)(addr))
+#  define BIO_set_conn_ip_family(b,f)   BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f)
+#  define BIO_get_conn_hostname(b)      ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0))
+#  define BIO_get_conn_port(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1))
+#  define BIO_get_conn_address(b)       ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2))
+#  define BIO_get_conn_ip_family(b)     BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
+#  define BIO_set_conn_mode(b,n)        BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL)
+
+/* BIO_s_accept() */
+#  define BIO_set_accept_name(b,name)   BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \
+                                                 (char *)(name))
+#  define BIO_set_accept_port(b,port)   BIO_ctrl(b,BIO_C_SET_ACCEPT,1, \
+                                                 (char *)(port))
+#  define BIO_get_accept_name(b)        ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0))
+#  define BIO_get_accept_port(b)        ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1))
+#  define BIO_get_peer_name(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2))
+#  define BIO_get_peer_port(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3))
+/* #define BIO_set_nbio(b,n)    BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#  define BIO_set_nbio_accept(b,n)      BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL)
+#  define BIO_set_accept_bios(b,bio)    BIO_ctrl(b,BIO_C_SET_ACCEPT,3, \
+                                                 (char *)(bio))
+#  define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f)
+#  define BIO_get_accept_ip_family(b)   BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL)
+
+/* Aliases kept for backward compatibility */
+#  define BIO_BIND_NORMAL                 0
+#  define BIO_BIND_REUSEADDR              BIO_SOCK_REUSEADDR
+#  define BIO_BIND_REUSEADDR_IF_UNUSED    BIO_SOCK_REUSEADDR
+#  define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#  define BIO_get_bind_mode(b)    BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+/* BIO_s_accept() and BIO_s_connect() */
+#  define BIO_do_connect(b)       BIO_do_handshake(b)
+#  define BIO_do_accept(b)        BIO_do_handshake(b)
+# endif /* OPENSSL_NO_SOCK */
+
+# define BIO_do_handshake(b)     BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */
+# define BIO_set_fd(b,fd,c)      BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+# define BIO_get_fd(b,c)         BIO_ctrl(b,BIO_C_GET_FD,0,(char *)(c))
+
+/* BIO_s_file() */
+# define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)(fp))
+# define BIO_get_fp(b,fpp)       BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)(fpp))
+
+/* BIO_s_fd() and BIO_s_file() */
+# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+# define BIO_tell(b)     (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/*
+ * name is cast to lose const, but might be better to route through a
+ * function so we can do it safely
+ */
+# ifdef CONST_STRICT
+/*
+ * If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b, const char *name);
+# else
+#  define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ,(char *)(name))
+# endif
+# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_WRITE,name)
+# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_APPEND,name)
+# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/*
+ * WARNING WARNING, this ups the reference count on the read bio of the SSL
+ * structure.  This is because the ssl read BIO is now pointed to by the
+ * next_bio field in the bio.  So when you free the BIO, make sure you are
+ * doing a BIO_free_all() to catch the underlying BIO.
+ */
+# define BIO_set_ssl(b,ssl,c)    BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)(ssl))
+# define BIO_get_ssl(b,sslp)     BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)(sslp))
+# define BIO_set_ssl_mode(b,client)      BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+# define BIO_set_ssl_renegotiate_bytes(b,num) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL)
+# define BIO_get_num_renegotiates(b) \
+        BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL)
+# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL)
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)     BIO_ctrl(b,BIO_C_SET_MD,1,(char *)(md)) */
+
+# define BIO_get_mem_data(b,pp)  BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)(pp))
+# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)(bm))
+# define BIO_get_mem_ptr(b,pp)   BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0, \
+                                          (char *)(pp))
+# define BIO_set_mem_eof_return(b,v) \
+                                BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+# define BIO_get_buffer_num_lines(b)     BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+# define BIO_set_buffer_size(b,size)     BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+# define BIO_dup_state(b,ret)    BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+# define BIO_reset(b)            (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+# define BIO_eof(b)              (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+# define BIO_set_close(b,c)      (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+# define BIO_get_close(b)        (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+# define BIO_pending(b)          (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+# define BIO_wpending(b)         (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+# define BIO_flush(b)            (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+                                                   cbp)
+# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+# define BIO_buffer_peek(b,s,l) BIO_ctrl(b,BIO_CTRL_PEEK,(l),(s))
+
+/* For BIO_s_bio() */
+# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+# define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+# define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+# define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)(peer))
+# define BIO_ctrl_set_connected(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)(peer))
+# define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+# define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+# define BIO_dgram_get_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer))
+# define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer))
+# define BIO_dgram_get_mtu_overhead(b) \
+         (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
+
+#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef)
+int BIO_set_ex_data(BIO *bio, int idx, void *data);
+void *BIO_get_ex_data(BIO *bio, int idx);
+uint64_t BIO_number_read(BIO *bio);
+uint64_t BIO_number_written(BIO *bio);
+
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free);
+
+const BIO_METHOD *BIO_s_file(void);
+BIO *BIO_new_file(const char *filename, const char *mode);
+# ifndef OPENSSL_NO_STDIO
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+# endif
+BIO *BIO_new(const BIO_METHOD *type);
+int BIO_free(BIO *a);
+void BIO_set_data(BIO *a, void *ptr);
+void *BIO_get_data(BIO *a);
+void BIO_set_init(BIO *a, int init);
+int BIO_get_init(BIO *a);
+void BIO_set_shutdown(BIO *a, int shut);
+int BIO_get_shutdown(BIO *a);
+void BIO_vfree(BIO *a);
+int BIO_up_ref(BIO *a);
+int BIO_read(BIO *b, void *data, int dlen);
+int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes);
+int BIO_gets(BIO *bp, char *buf, int size);
+int BIO_write(BIO *b, const void *data, int dlen);
+int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written);
+int BIO_puts(BIO *bp, const char *buf);
+int BIO_indent(BIO *b, int indent, int max);
+long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
+void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
+long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
+BIO *BIO_push(BIO *b, BIO *append);
+BIO *BIO_pop(BIO *b);
+void BIO_free_all(BIO *a);
+BIO *BIO_find_type(BIO *b, int bio_type);
+BIO *BIO_next(BIO *b);
+void BIO_set_next(BIO *b, BIO *next);
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
+int BIO_get_retry_reason(BIO *bio);
+void BIO_set_retry_reason(BIO *bio, int reason);
+BIO *BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
+                        long argl, long ret);
+
+const BIO_METHOD *BIO_s_mem(void);
+const BIO_METHOD *BIO_s_secmem(void);
+BIO *BIO_new_mem_buf(const void *buf, int len);
+# ifndef OPENSSL_NO_SOCK
+const BIO_METHOD *BIO_s_socket(void);
+const BIO_METHOD *BIO_s_connect(void);
+const BIO_METHOD *BIO_s_accept(void);
+# endif
+const BIO_METHOD *BIO_s_fd(void);
+const BIO_METHOD *BIO_s_log(void);
+const BIO_METHOD *BIO_s_bio(void);
+const BIO_METHOD *BIO_s_null(void);
+const BIO_METHOD *BIO_f_null(void);
+const BIO_METHOD *BIO_f_buffer(void);
+const BIO_METHOD *BIO_f_linebuffer(void);
+const BIO_METHOD *BIO_f_nbio_test(void);
+# ifndef OPENSSL_NO_DGRAM
+const BIO_METHOD *BIO_s_datagram(void);
+int BIO_dgram_non_fatal_error(int error);
+BIO *BIO_new_dgram(int fd, int close_flag);
+#  ifndef OPENSSL_NO_SCTP
+const BIO_METHOD *BIO_s_datagram_sctp(void);
+BIO *BIO_new_dgram_sctp(int fd, int close_flag);
+int BIO_dgram_is_sctp(BIO *bio);
+int BIO_dgram_sctp_notification_cb(BIO *b,
+                                   void (*handle_notifications) (BIO *bio,
+                                                                 void *context,
+                                                                 void *buf),
+                                   void *context);
+int BIO_dgram_sctp_wait_for_dry(BIO *b);
+int BIO_dgram_sctp_msg_waiting(BIO *b);
+#  endif
+# endif
+
+# ifndef OPENSSL_NO_SOCK
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+# endif
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+                void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+                       void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b, const char *bytes, int len);
+int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
+# ifndef OPENSSL_NO_STDIO
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+# endif
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen);
+
+# ifndef OPENSSL_NO_SOCK
+BIO_ADDR *BIO_ADDR_new(void);
+int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
+                     const void *where, size_t wherelen, unsigned short port);
+void BIO_ADDR_free(BIO_ADDR *);
+void BIO_ADDR_clear(BIO_ADDR *ap);
+int BIO_ADDR_family(const BIO_ADDR *ap);
+int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l);
+unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap);
+char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric);
+char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric);
+char *BIO_ADDR_path_string(const BIO_ADDR *ap);
+
+const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai);
+const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai);
+void BIO_ADDRINFO_free(BIO_ADDRINFO *bai);
+
+enum BIO_hostserv_priorities {
+    BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV
+};
+int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
+                       enum BIO_hostserv_priorities hostserv_prio);
+enum BIO_lookup_type {
+    BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER
+};
+int BIO_lookup(const char *host, const char *service,
+               enum BIO_lookup_type lookup_type,
+               int family, int socktype, BIO_ADDRINFO **res);
+int BIO_lookup_ex(const char *host, const char *service,
+                  int lookup_type, int family, int socktype, int protocol,
+                  BIO_ADDRINFO **res);
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd, int mode);
+int BIO_sock_init(void);
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define BIO_sock_cleanup() while(0) continue
+# endif
+int BIO_set_tcp_ndelay(int sock, int turn_on);
+
+DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name))
+DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr))
+DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip))
+DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode))
+DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port))
+
+union BIO_sock_info_u {
+    BIO_ADDR *addr;
+};
+enum BIO_sock_info_type {
+    BIO_SOCK_INFO_ADDRESS
+};
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info);
+
+#  define BIO_SOCK_REUSEADDR    0x01
+#  define BIO_SOCK_V6_ONLY      0x02
+#  define BIO_SOCK_KEEPALIVE    0x04
+#  define BIO_SOCK_NONBLOCK     0x08
+#  define BIO_SOCK_NODELAY      0x10
+
+int BIO_socket(int domain, int socktype, int protocol, int options);
+int BIO_connect(int sock, const BIO_ADDR *addr, int options);
+int BIO_bind(int sock, const BIO_ADDR *addr, int options);
+int BIO_listen(int sock, const BIO_ADDR *addr, int options);
+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options);
+int BIO_closesocket(int sock);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_connect(const char *host_port);
+BIO *BIO_new_accept(const char *host_port);
+# endif /* OPENSSL_NO_SOCK*/
+
+BIO *BIO_new_fd(int fd, int close_flag);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+                     BIO **bio2, size_t writebuf2);
+/*
+ * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default
+ * value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*
+ * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+ */
+
+# define ossl_bio__attr__(x)
+# if defined(__GNUC__) && defined(__STDC_VERSION__) \
+    && !defined(__APPLE__)
+    /*
+     * Because we support the 'z' modifier, which made its appearance in C99,
+     * we can't use __attribute__ with pre C99 dialects.
+     */
+#  if __STDC_VERSION__ >= 199901L
+#   undef ossl_bio__attr__
+#   define ossl_bio__attr__ __attribute__
+#   if __GNUC__*10 + __GNUC_MINOR__ >= 44
+#    define ossl_bio__printf__ __gnu_printf__
+#   else
+#    define ossl_bio__printf__ __printf__
+#   endif
+#  endif
+# endif
+int BIO_printf(BIO *bio, const char *format, ...)
+ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 0)));
+# undef ossl_bio__attr__
+# undef ossl_bio__printf__
+
+
+BIO_METHOD *BIO_meth_new(int type, const char *name);
+void BIO_meth_free(BIO_METHOD *biom);
+int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int);
+int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t,
+                                                size_t *);
+int BIO_meth_set_write(BIO_METHOD *biom,
+                       int (*write) (BIO *, const char *, int));
+int BIO_meth_set_write_ex(BIO_METHOD *biom,
+                       int (*bwrite) (BIO *, const char *, size_t, size_t *));
+int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int);
+int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *);
+int BIO_meth_set_read(BIO_METHOD *biom,
+                      int (*read) (BIO *, char *, int));
+int BIO_meth_set_read_ex(BIO_METHOD *biom,
+                         int (*bread) (BIO *, char *, size_t, size_t *));
+int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *);
+int BIO_meth_set_puts(BIO_METHOD *biom,
+                      int (*puts) (BIO *, const char *));
+int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int);
+int BIO_meth_set_gets(BIO_METHOD *biom,
+                      int (*gets) (BIO *, char *, int));
+long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *);
+int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                      long (*ctrl) (BIO *, int, long, void *));
+int (*BIO_meth_get_create(const BIO_METHOD *bion)) (BIO *);
+int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *));
+int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *);
+int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *));
+long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))
+                                 (BIO *, int, BIO_info_cb *);
+int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
+                               long (*callback_ctrl) (BIO *, int,
+                                                      BIO_info_cb *));
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 124 - 0
rambus_sec_lib/include/openssl/bioerr.h

@@ -0,0 +1,124 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BIOERR_H
+# define HEADER_BIOERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_BIO_strings(void);
+
+/*
+ * BIO function codes.
+ */
+# define BIO_F_ACPT_STATE                                 100
+# define BIO_F_ADDRINFO_WRAP                              148
+# define BIO_F_ADDR_STRINGS                               134
+# define BIO_F_BIO_ACCEPT                                 101
+# define BIO_F_BIO_ACCEPT_EX                              137
+# define BIO_F_BIO_ACCEPT_NEW                             152
+# define BIO_F_BIO_ADDR_NEW                               144
+# define BIO_F_BIO_BIND                                   147
+# define BIO_F_BIO_CALLBACK_CTRL                          131
+# define BIO_F_BIO_CONNECT                                138
+# define BIO_F_BIO_CONNECT_NEW                            153
+# define BIO_F_BIO_CTRL                                   103
+# define BIO_F_BIO_GETS                                   104
+# define BIO_F_BIO_GET_HOST_IP                            106
+# define BIO_F_BIO_GET_NEW_INDEX                          102
+# define BIO_F_BIO_GET_PORT                               107
+# define BIO_F_BIO_LISTEN                                 139
+# define BIO_F_BIO_LOOKUP                                 135
+# define BIO_F_BIO_LOOKUP_EX                              143
+# define BIO_F_BIO_MAKE_PAIR                              121
+# define BIO_F_BIO_METH_NEW                               146
+# define BIO_F_BIO_NEW                                    108
+# define BIO_F_BIO_NEW_DGRAM_SCTP                         145
+# define BIO_F_BIO_NEW_FILE                               109
+# define BIO_F_BIO_NEW_MEM_BUF                            126
+# define BIO_F_BIO_NREAD                                  123
+# define BIO_F_BIO_NREAD0                                 124
+# define BIO_F_BIO_NWRITE                                 125
+# define BIO_F_BIO_NWRITE0                                122
+# define BIO_F_BIO_PARSE_HOSTSERV                         136
+# define BIO_F_BIO_PUTS                                   110
+# define BIO_F_BIO_READ                                   111
+# define BIO_F_BIO_READ_EX                                105
+# define BIO_F_BIO_READ_INTERN                            120
+# define BIO_F_BIO_SOCKET                                 140
+# define BIO_F_BIO_SOCKET_NBIO                            142
+# define BIO_F_BIO_SOCK_INFO                              141
+# define BIO_F_BIO_SOCK_INIT                              112
+# define BIO_F_BIO_WRITE                                  113
+# define BIO_F_BIO_WRITE_EX                               119
+# define BIO_F_BIO_WRITE_INTERN                           128
+# define BIO_F_BUFFER_CTRL                                114
+# define BIO_F_CONN_CTRL                                  127
+# define BIO_F_CONN_STATE                                 115
+# define BIO_F_DGRAM_SCTP_NEW                             149
+# define BIO_F_DGRAM_SCTP_READ                            132
+# define BIO_F_DGRAM_SCTP_WRITE                           133
+# define BIO_F_DOAPR_OUTCH                                150
+# define BIO_F_FILE_CTRL                                  116
+# define BIO_F_FILE_READ                                  130
+# define BIO_F_LINEBUFFER_CTRL                            129
+# define BIO_F_LINEBUFFER_NEW                             151
+# define BIO_F_MEM_WRITE                                  117
+# define BIO_F_NBIOF_NEW                                  154
+# define BIO_F_SLG_WRITE                                  155
+# define BIO_F_SSL_NEW                                    118
+
+/*
+ * BIO reason codes.
+ */
+# define BIO_R_ACCEPT_ERROR                               100
+# define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET               141
+# define BIO_R_AMBIGUOUS_HOST_OR_SERVICE                  129
+# define BIO_R_BAD_FOPEN_MODE                             101
+# define BIO_R_BROKEN_PIPE                                124
+# define BIO_R_CONNECT_ERROR                              103
+# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET          107
+# define BIO_R_GETSOCKNAME_ERROR                          132
+# define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS              133
+# define BIO_R_GETTING_SOCKTYPE                           134
+# define BIO_R_INVALID_ARGUMENT                           125
+# define BIO_R_INVALID_SOCKET                             135
+# define BIO_R_IN_USE                                     123
+# define BIO_R_LENGTH_TOO_LONG                            102
+# define BIO_R_LISTEN_V6_ONLY                             136
+# define BIO_R_LOOKUP_RETURNED_NOTHING                    142
+# define BIO_R_MALFORMED_HOST_OR_SERVICE                  130
+# define BIO_R_NBIO_CONNECT_ERROR                         110
+# define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED        143
+# define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED           144
+# define BIO_R_NO_PORT_DEFINED                            113
+# define BIO_R_NO_SUCH_FILE                               128
+# define BIO_R_NULL_PARAMETER                             115
+# define BIO_R_UNABLE_TO_BIND_SOCKET                      117
+# define BIO_R_UNABLE_TO_CREATE_SOCKET                    118
+# define BIO_R_UNABLE_TO_KEEPALIVE                        137
+# define BIO_R_UNABLE_TO_LISTEN_SOCKET                    119
+# define BIO_R_UNABLE_TO_NODELAY                          138
+# define BIO_R_UNABLE_TO_REUSEADDR                        139
+# define BIO_R_UNAVAILABLE_IP_FAMILY                      145
+# define BIO_R_UNINITIALIZED                              120
+# define BIO_R_UNKNOWN_INFO_TYPE                          140
+# define BIO_R_UNSUPPORTED_IP_FAMILY                      146
+# define BIO_R_UNSUPPORTED_METHOD                         121
+# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY                131
+# define BIO_R_WRITE_TO_READ_ONLY_BIO                     126
+# define BIO_R_WSASTARTUP                                 122
+
+#endif

+ 61 - 0
rambus_sec_lib/include/openssl/blowfish.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BLOWFISH_H
+# define HEADER_BLOWFISH_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_BF
+# include <openssl/e_os2.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define BF_ENCRYPT      1
+# define BF_DECRYPT      0
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide.                     !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+# define BF_LONG unsigned int
+
+# define BF_ROUNDS       16
+# define BF_BLOCK        8
+
+typedef struct bf_key_st {
+    BF_LONG P[BF_ROUNDS + 2];
+    BF_LONG S[4 * 256];
+} BF_KEY;
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key);
+void BF_decrypt(BF_LONG *data, const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                    const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif

+ 539 - 0
rambus_sec_lib/include/openssl/bn.h

@@ -0,0 +1,539 @@
+/*
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BN_H
+# define HEADER_BN_H
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <openssl/opensslconf.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/crypto.h>
+# include <openssl/bnerr.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 64-bit processor with LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT_LONG
+#  define BN_ULONG        unsigned long
+#  define BN_BYTES        8
+# endif
+
+/*
+ * 64-bit processor other than LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT
+#  define BN_ULONG        unsigned long long
+#  define BN_BYTES        8
+# endif
+
+# ifdef THIRTY_TWO_BIT
+#  define BN_ULONG        unsigned int
+#  define BN_BYTES        4
+# endif
+
+# define BN_BITS2       (BN_BYTES * 8)
+# define BN_BITS        (BN_BITS2 * 2)
+# define BN_TBIT        ((BN_ULONG)1 << (BN_BITS2 - 1))
+
+# define BN_FLG_MALLOCED         0x01
+# define BN_FLG_STATIC_DATA      0x02
+
+/*
+ * avoid leaking exponent information through timing,
+ * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+ * BN_div() will call BN_div_no_branch,
+ * BN_mod_inverse() will call bn_mod_inverse_no_branch.
+ */
+# define BN_FLG_CONSTTIME        0x04
+# define BN_FLG_SECURE           0x08
+
+# if OPENSSL_API_COMPAT < 0x00908000L
+/* deprecated name for the flag */
+#  define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME
+#  define BN_FLG_FREE            0x8000 /* used for debugging */
+# endif
+
+void BN_set_flags(BIGNUM *b, int n);
+int BN_get_flags(const BIGNUM *b, int n);
+
+/* Values for |top| in BN_rand() */
+#define BN_RAND_TOP_ANY    -1
+#define BN_RAND_TOP_ONE     0
+#define BN_RAND_TOP_TWO     1
+
+/* Values for |bottom| in BN_rand() */
+#define BN_RAND_BOTTOM_ANY  0
+#define BN_RAND_BOTTOM_ODD  1
+
+/*
+ * get a clone of a BIGNUM with changed flags, for *temporary* use only (the
+ * two BIGNUMs cannot be used in parallel!). Also only for *read only* use. The
+ * value |dest| should be a newly allocated BIGNUM obtained via BN_new() that
+ * has not been otherwise initialised or used.
+ */
+void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags);
+
+/* Wrapper function to make using BN_GENCB easier */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+
+BN_GENCB *BN_GENCB_new(void);
+void BN_GENCB_free(BN_GENCB *cb);
+
+/* Populate a BN_GENCB structure with an "old"-style callback */
+void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *),
+                      void *cb_arg);
+
+/* Populate a BN_GENCB structure with a "new"-style callback */
+void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *),
+                  void *cb_arg);
+
+void *BN_GENCB_get_arg(BN_GENCB *cb);
+
+# define BN_prime_checks 0      /* default: select number of iterations based
+                                 * on the size of the number */
+
+/*
+ * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations
+ * that will be done for checking that a random number is probably prime. The
+ * error rate for accepting a composite number as prime depends on the size of
+ * the prime |b|. The error rates used are for calculating an RSA key with 2 primes,
+ * and so the level is what you would expect for a key of double the size of the
+ * prime.
+ *
+ * This table is generated using the algorithm of FIPS PUB 186-4
+ * Digital Signature Standard (DSS), section F.1, page 117.
+ * (https://dx.doi.org/10.6028/NIST.FIPS.186-4)
+ *
+ * The following magma script was used to generate the output:
+ * securitybits:=125;
+ * k:=1024;
+ * for t:=1 to 65 do
+ *   for M:=3 to Floor(2*Sqrt(k-1)-1) do
+ *     S:=0;
+ *     // Sum over m
+ *     for m:=3 to M do
+ *       s:=0;
+ *       // Sum over j
+ *       for j:=2 to m do
+ *         s+:=(RealField(32)!2)^-(j+(k-1)/j);
+ *       end for;
+ *       S+:=2^(m-(m-1)*t)*s;
+ *     end for;
+ *     A:=2^(k-2-M*t);
+ *     B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S;
+ *     pkt:=2.00743*Log(2)*k*2^-k*(A+B);
+ *     seclevel:=Floor(-Log(2,pkt));
+ *     if seclevel ge securitybits then
+ *       printf "k: %5o, security: %o bits  (t: %o, M: %o)\n",k,seclevel,t,M;
+ *       break;
+ *     end if;
+ *   end for;
+ *   if seclevel ge securitybits then break; end if;
+ * end for;
+ *
+ * It can be run online at:
+ * http://magma.maths.usyd.edu.au/calc
+ *
+ * And will output:
+ * k:  1024, security: 129 bits  (t: 6, M: 23)
+ *
+ * k is the number of bits of the prime, securitybits is the level we want to
+ * reach.
+ *
+ * prime length | RSA key size | # MR tests | security level
+ * -------------+--------------|------------+---------------
+ *  (b) >= 6394 |     >= 12788 |          3 |        256 bit
+ *  (b) >= 3747 |     >=  7494 |          3 |        192 bit
+ *  (b) >= 1345 |     >=  2690 |          4 |        128 bit
+ *  (b) >= 1080 |     >=  2160 |          5 |        128 bit
+ *  (b) >=  852 |     >=  1704 |          5 |        112 bit
+ *  (b) >=  476 |     >=   952 |          5 |         80 bit
+ *  (b) >=  400 |     >=   800 |          6 |         80 bit
+ *  (b) >=  347 |     >=   694 |          7 |         80 bit
+ *  (b) >=  308 |     >=   616 |          8 |         80 bit
+ *  (b) >=   55 |     >=   110 |         27 |         64 bit
+ *  (b) >=    6 |     >=    12 |         34 |         64 bit
+ */
+
+# define BN_prime_checks_for_size(b) ((b) >= 3747 ?  3 : \
+                                (b) >=  1345 ?  4 : \
+                                (b) >=  476 ?  5 : \
+                                (b) >=  400 ?  6 : \
+                                (b) >=  347 ?  7 : \
+                                (b) >=  308 ?  8 : \
+                                (b) >=  55  ? 27 : \
+                                /* b >= 6 */ 34)
+
+# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+
+int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
+int BN_is_zero(const BIGNUM *a);
+int BN_is_one(const BIGNUM *a);
+int BN_is_word(const BIGNUM *a, const BN_ULONG w);
+int BN_is_odd(const BIGNUM *a);
+
+# define BN_one(a)       (BN_set_word((a),1))
+
+void BN_zero_ex(BIGNUM *a);
+
+# if OPENSSL_API_COMPAT >= 0x00908000L
+#  define BN_zero(a)      BN_zero_ex(a)
+# else
+#  define BN_zero(a)      (BN_set_word((a),0))
+# endif
+
+const BIGNUM *BN_value_one(void);
+char *BN_options(void);
+BN_CTX *BN_CTX_new(void);
+BN_CTX *BN_CTX_secure_new(void);
+void BN_CTX_free(BN_CTX *c);
+void BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void BN_CTX_end(BN_CTX *ctx);
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG l);
+int BN_security_bits(int L, int N);
+BIGNUM *BN_new(void);
+BIGNUM *BN_secure_new(void);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
+BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
+BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param  b  pointer to the BIGNUM object
+ * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise
+ */
+void BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param  b  pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+int BN_is_negative(const BIGNUM *b);
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+           BN_CTX *ctx);
+# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m);
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m);
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+                  BN_CTX *ctx);
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+               const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                              const BIGNUM *m, BN_CTX *ctx,
+                              BN_MONT_CTX *in_mont);
+int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                      const BIGNUM *m, BN_CTX *ctx);
+
+int BN_mask_bits(BIGNUM *a, int n);
+# ifndef OPENSSL_NO_STDIO
+int BN_print_fp(FILE *fp, const BIGNUM *a);
+# endif
+int BN_print(BIO *bio, const BIGNUM *a);
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+char *BN_bn2hex(const BIGNUM *a);
+char *BN_bn2dec(const BIGNUM *a);
+int BN_hex2bn(BIGNUM **a, const char *str);
+int BN_dec2bn(BIGNUM **a, const char *str);
+int BN_asc2bn(BIGNUM **a, const char *str);
+int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns
+                                                                  * -2 for
+                                                                  * error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+                    const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
+/* Deprecated versions */
+DEPRECATEDIN_0_9_8(BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+                                             const BIGNUM *add,
+                                             const BIGNUM *rem,
+                                             void (*callback) (int, int,
+                                                               void *),
+                                             void *cb_arg))
+DEPRECATEDIN_0_9_8(int
+                   BN_is_prime(const BIGNUM *p, int nchecks,
+                               void (*callback) (int, int, void *),
+                               BN_CTX *ctx, void *cb_arg))
+DEPRECATEDIN_0_9_8(int
+                   BN_is_prime_fasttest(const BIGNUM *p, int nchecks,
+                                        void (*callback) (int, int, void *),
+                                        BN_CTX *ctx, void *cb_arg,
+                                        int do_trial_division))
+
+/* Newer versions */
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+                         const BIGNUM *rem, BN_GENCB *cb);
+int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx,
+                            int do_trial_division, BN_GENCB *cb);
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+                            const BIGNUM *Xp, const BIGNUM *Xp1,
+                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+                            BN_GENCB *cb);
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1,
+                              BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e,
+                              BN_CTX *ctx, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void);
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                          BN_MONT_CTX *mont, BN_CTX *ctx);
+int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+                     BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+                       BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock,
+                                    const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+# define BN_BLINDING_NO_UPDATE   0x00000001
+# define BN_BLINDING_NO_RECREATE 0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+                          BN_CTX *);
+
+int BN_BLINDING_is_current_thread(BN_BLINDING *b);
+void BN_BLINDING_set_current_thread(BN_BLINDING *b);
+int BN_BLINDING_lock(BN_BLINDING *b);
+int BN_BLINDING_unlock(BN_BLINDING *b);
+
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+                                      const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+                                      int (*bn_mod_exp) (BIGNUM *r,
+                                                         const BIGNUM *a,
+                                                         const BIGNUM *p,
+                                                         const BIGNUM *m,
+                                                         BN_CTX *ctx,
+                                                         BN_MONT_CTX *m_ctx),
+                                      BN_MONT_CTX *m_ctx);
+
+DEPRECATEDIN_0_9_8(void BN_set_params(int mul, int high, int low, int mont))
+DEPRECATEDIN_0_9_8(int BN_get_params(int which)) /* 0, mul, 1 high, 2 low, 3
+                                                  * mont */
+
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+                          BN_RECP_CTX *recp, BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+                BN_RECP_CTX *recp, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+
+/*
+ * Functions for arithmetic over binary polynomials represented by BIGNUMs.
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored. Note that input arguments are not const so that their bit arrays
+ * can be expanded to the appropriate size if needed.
+ */
+
+/*
+ * r = a + b
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+#  define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+/*
+ * r=a mod p
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = (a ^ b) mod p */
+int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                     BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                           BN_CTX *ctx);
+#  define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/*-
+ * Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+/* r = a mod p */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+                        BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
+                        BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = (a ^ b) mod p */
+int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+                         const int p[], BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+                               const int p[], BN_CTX *ctx);
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+
+# endif
+
+/*
+ * faster mod functions for the 'NIST primes' 0 <= a < p^2
+ */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
+                                          const BIGNUM *field, BN_CTX *ctx);
+
+int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
+                          const BIGNUM *priv, const unsigned char *message,
+                          size_t message_len, BN_CTX *ctx);
+
+/* Primes from RFC 2409 */
+BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define get_rfc2409_prime_768 BN_get_rfc2409_prime_768
+#  define get_rfc2409_prime_1024 BN_get_rfc2409_prime_1024
+#  define get_rfc3526_prime_1536 BN_get_rfc3526_prime_1536
+#  define get_rfc3526_prime_2048 BN_get_rfc3526_prime_2048
+#  define get_rfc3526_prime_3072 BN_get_rfc3526_prime_3072
+#  define get_rfc3526_prime_4096 BN_get_rfc3526_prime_4096
+#  define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144
+#  define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192
+# endif
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 100 - 0
rambus_sec_lib/include/openssl/bnerr.h

@@ -0,0 +1,100 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BNERR_H
+# define HEADER_BNERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_BN_strings(void);
+
+/*
+ * BN function codes.
+ */
+# define BN_F_BNRAND                                      127
+# define BN_F_BNRAND_RANGE                                138
+# define BN_F_BN_BLINDING_CONVERT_EX                      100
+# define BN_F_BN_BLINDING_CREATE_PARAM                    128
+# define BN_F_BN_BLINDING_INVERT_EX                       101
+# define BN_F_BN_BLINDING_NEW                             102
+# define BN_F_BN_BLINDING_UPDATE                          103
+# define BN_F_BN_BN2DEC                                   104
+# define BN_F_BN_BN2HEX                                   105
+# define BN_F_BN_COMPUTE_WNAF                             142
+# define BN_F_BN_CTX_GET                                  116
+# define BN_F_BN_CTX_NEW                                  106
+# define BN_F_BN_CTX_START                                129
+# define BN_F_BN_DIV                                      107
+# define BN_F_BN_DIV_RECP                                 130
+# define BN_F_BN_EXP                                      123
+# define BN_F_BN_EXPAND_INTERNAL                          120
+# define BN_F_BN_GENCB_NEW                                143
+# define BN_F_BN_GENERATE_DSA_NONCE                       140
+# define BN_F_BN_GENERATE_PRIME_EX                        141
+# define BN_F_BN_GF2M_MOD                                 131
+# define BN_F_BN_GF2M_MOD_EXP                             132
+# define BN_F_BN_GF2M_MOD_MUL                             133
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD                      134
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR                  135
+# define BN_F_BN_GF2M_MOD_SQR                             136
+# define BN_F_BN_GF2M_MOD_SQRT                            137
+# define BN_F_BN_LSHIFT                                   145
+# define BN_F_BN_MOD_EXP2_MONT                            118
+# define BN_F_BN_MOD_EXP_MONT                             109
+# define BN_F_BN_MOD_EXP_MONT_CONSTTIME                   124
+# define BN_F_BN_MOD_EXP_MONT_WORD                        117
+# define BN_F_BN_MOD_EXP_RECP                             125
+# define BN_F_BN_MOD_EXP_SIMPLE                           126
+# define BN_F_BN_MOD_INVERSE                              110
+# define BN_F_BN_MOD_INVERSE_NO_BRANCH                    139
+# define BN_F_BN_MOD_LSHIFT_QUICK                         119
+# define BN_F_BN_MOD_SQRT                                 121
+# define BN_F_BN_MONT_CTX_NEW                             149
+# define BN_F_BN_MPI2BN                                   112
+# define BN_F_BN_NEW                                      113
+# define BN_F_BN_POOL_GET                                 147
+# define BN_F_BN_RAND                                     114
+# define BN_F_BN_RAND_RANGE                               122
+# define BN_F_BN_RECP_CTX_NEW                             150
+# define BN_F_BN_RSHIFT                                   146
+# define BN_F_BN_SET_WORDS                                144
+# define BN_F_BN_STACK_PUSH                               148
+# define BN_F_BN_USUB                                     115
+
+/*
+ * BN reason codes.
+ */
+# define BN_R_ARG2_LT_ARG3                                100
+# define BN_R_BAD_RECIPROCAL                              101
+# define BN_R_BIGNUM_TOO_LONG                             114
+# define BN_R_BITS_TOO_SMALL                              118
+# define BN_R_CALLED_WITH_EVEN_MODULUS                    102
+# define BN_R_DIV_BY_ZERO                                 103
+# define BN_R_ENCODING_ERROR                              104
+# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA                105
+# define BN_R_INPUT_NOT_REDUCED                           110
+# define BN_R_INVALID_LENGTH                              106
+# define BN_R_INVALID_RANGE                               115
+# define BN_R_INVALID_SHIFT                               119
+# define BN_R_NOT_A_SQUARE                                111
+# define BN_R_NOT_INITIALIZED                             107
+# define BN_R_NO_INVERSE                                  108
+# define BN_R_NO_SOLUTION                                 116
+# define BN_R_PRIVATE_KEY_TOO_LARGE                       117
+# define BN_R_P_IS_NOT_PRIME                              112
+# define BN_R_TOO_MANY_ITERATIONS                         113
+# define BN_R_TOO_MANY_TEMPORARY_VARIABLES                109
+
+#endif

+ 58 - 0
rambus_sec_lib/include/openssl/buffer.h

@@ -0,0 +1,58 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BUFFER_H
+# define HEADER_BUFFER_H
+
+# include <openssl/ossl_typ.h>
+# ifndef HEADER_CRYPTO_H
+#  include <openssl/crypto.h>
+# endif
+# include <openssl/buffererr.h>
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <stddef.h>
+# include <sys/types.h>
+
+/*
+ * These names are outdated as of OpenSSL 1.1; a future release
+ * will move them to be deprecated.
+ */
+# define BUF_strdup(s) OPENSSL_strdup(s)
+# define BUF_strndup(s, size) OPENSSL_strndup(s, size)
+# define BUF_memdup(data, size) OPENSSL_memdup(data, size)
+# define BUF_strlcpy(dst, src, size)  OPENSSL_strlcpy(dst, src, size)
+# define BUF_strlcat(dst, src, size) OPENSSL_strlcat(dst, src, size)
+# define BUF_strnlen(str, maxlen) OPENSSL_strnlen(str, maxlen)
+
+struct buf_mem_st {
+    size_t length;              /* current number of bytes */
+    char *data;
+    size_t max;                 /* size of buffer */
+    unsigned long flags;
+};
+
+# define BUF_MEM_FLAG_SECURE  0x01
+
+BUF_MEM *BUF_MEM_new(void);
+BUF_MEM *BUF_MEM_new_ex(unsigned long flags);
+void BUF_MEM_free(BUF_MEM *a);
+size_t BUF_MEM_grow(BUF_MEM *str, size_t len);
+size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);
+
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 34 - 0
rambus_sec_lib/include/openssl/buffererr.h

@@ -0,0 +1,34 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BUFERR_H
+# define HEADER_BUFERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_BUF_strings(void);
+
+/*
+ * BUF function codes.
+ */
+# define BUF_F_BUF_MEM_GROW                               100
+# define BUF_F_BUF_MEM_GROW_CLEAN                         105
+# define BUF_F_BUF_MEM_NEW                                101
+
+/*
+ * BUF reason codes.
+ */
+
+#endif

+ 83 - 0
rambus_sec_lib/include/openssl/camellia.h

@@ -0,0 +1,83 @@
+/*
+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CAMELLIA_H
+# define HEADER_CAMELLIA_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CAMELLIA
+# include <stddef.h>
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define CAMELLIA_ENCRYPT        1
+# define CAMELLIA_DECRYPT        0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+
+/* This should be a hidden type, but EVP requires that the size be known */
+
+# define CAMELLIA_BLOCK_SIZE 16
+# define CAMELLIA_TABLE_BYTE_LEN 272
+# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match
+                                                               * with WORD */
+
+struct camellia_key_st {
+    union {
+        double d;               /* ensures 64-bit align */
+        KEY_TABLE_TYPE rd_key;
+    } u;
+    int grand_rounds;
+};
+typedef struct camellia_key_st CAMELLIA_KEY;
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+                     CAMELLIA_KEY *key);
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                          const CAMELLIA_KEY *key, const int enc);
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                          size_t length, const CAMELLIA_KEY *key,
+                          unsigned char *ivec, const int enc);
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num);
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+                             unsigned int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif

+ 53 - 0
rambus_sec_lib/include/openssl/cast.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CAST_H
+# define HEADER_CAST_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CAST
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define CAST_ENCRYPT    1
+# define CAST_DECRYPT    0
+
+# define CAST_LONG unsigned int
+
+# define CAST_BLOCK      8
+# define CAST_KEY_LENGTH 16
+
+typedef struct cast_key_st {
+    CAST_LONG data[32];
+    int short_key;              /* Use reduced rounds for short key */
+} CAST_KEY;
+
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAST_KEY *key, int enc);
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const CAST_KEY *ks, unsigned char *iv,
+                      int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif

+ 41 - 0
rambus_sec_lib/include/openssl/cmac.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CMAC_H
+# define HEADER_CMAC_H
+
+# ifndef OPENSSL_NO_CMAC
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/evp.h>
+
+/* Opaque */
+typedef struct CMAC_CTX_st CMAC_CTX;
+
+CMAC_CTX *CMAC_CTX_new(void);
+void CMAC_CTX_cleanup(CMAC_CTX *ctx);
+void CMAC_CTX_free(CMAC_CTX *ctx);
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+              const EVP_CIPHER *cipher, ENGINE *impl);
+int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
+int CMAC_resume(CMAC_CTX *ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+
+# endif
+#endif

+ 339 - 0
rambus_sec_lib/include/openssl/cms.h

@@ -0,0 +1,339 @@
+/*
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CMS_H
+# define HEADER_CMS_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CMS
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+# include <openssl/cmserr.h>
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+
+DEFINE_STACK_OF(CMS_SignerInfo)
+DEFINE_STACK_OF(CMS_RecipientEncryptedKey)
+DEFINE_STACK_OF(CMS_RecipientInfo)
+DEFINE_STACK_OF(CMS_RevocationInfoChoice)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_NONE              -1
+# define CMS_RECIPINFO_TRANS             0
+# define CMS_RECIPINFO_AGREE             1
+# define CMS_RECIPINFO_KEK               2
+# define CMS_RECIPINFO_PASS              3
+# define CMS_RECIPINFO_OTHER             4
+
+/* S/MIME related flags */
+
+# define CMS_TEXT                        0x1
+# define CMS_NOCERTS                     0x2
+# define CMS_NO_CONTENT_VERIFY           0x4
+# define CMS_NO_ATTR_VERIFY              0x8
+# define CMS_NOSIGS                      \
+                        (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+# define CMS_NOINTERN                    0x10
+# define CMS_NO_SIGNER_CERT_VERIFY       0x20
+# define CMS_NOVERIFY                    0x20
+# define CMS_DETACHED                    0x40
+# define CMS_BINARY                      0x80
+# define CMS_NOATTR                      0x100
+# define CMS_NOSMIMECAP                  0x200
+# define CMS_NOOLDMIMETYPE               0x400
+# define CMS_CRLFEOL                     0x800
+# define CMS_STREAM                      0x1000
+# define CMS_NOCRL                       0x2000
+# define CMS_PARTIAL                     0x4000
+# define CMS_REUSE_DIGEST                0x8000
+# define CMS_USE_KEYID                   0x10000
+# define CMS_DEBUG_DECRYPT               0x20000
+# define CMS_KEY_PARAM                   0x40000
+# define CMS_ASCIICRLF                   0x80000
+
+const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+# ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+# endif
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
+              unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+                               const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+                             const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         const unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+                                    unsigned char *pass,
+                                    ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+                                               int iter, int wrap_nid,
+                                               int pbe_nid,
+                                               unsigned char *pass,
+                                               ossl_ssize_t passlen,
+                                               const EVP_CIPHER *kekciph);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags);
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+                           unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig);
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                               int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj,
+                               int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
+                                  int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si,
+                                 const ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type);
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+                                               int allorfirst,
+                                               STACK_OF(GENERAL_NAMES)
+                                               *receiptList, STACK_OF(GENERAL_NAMES)
+                                               *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+                                    ASN1_STRING **pcid,
+                                    int *pallorfirst,
+                                    STACK_OF(GENERAL_NAMES) **plist,
+                                    STACK_OF(GENERAL_NAMES) **prto);
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm);
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert);
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert);
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk);
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek);
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen);
+
+/* Backward compatibility for spelling errors. */
+# define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM
+# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \
+    CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif

+ 202 - 0
rambus_sec_lib/include/openssl/cmserr.h

@@ -0,0 +1,202 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CMSERR_H
+# define HEADER_CMSERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CMS
+
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+int ERR_load_CMS_strings(void);
+
+/*
+ * CMS function codes.
+ */
+#  define CMS_F_CHECK_CONTENT                              99
+#  define CMS_F_CMS_ADD0_CERT                              164
+#  define CMS_F_CMS_ADD0_RECIPIENT_KEY                     100
+#  define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD                165
+#  define CMS_F_CMS_ADD1_RECEIPTREQUEST                    158
+#  define CMS_F_CMS_ADD1_RECIPIENT_CERT                    101
+#  define CMS_F_CMS_ADD1_SIGNER                            102
+#  define CMS_F_CMS_ADD1_SIGNINGTIME                       103
+#  define CMS_F_CMS_COMPRESS                               104
+#  define CMS_F_CMS_COMPRESSEDDATA_CREATE                  105
+#  define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO                106
+#  define CMS_F_CMS_COPY_CONTENT                           107
+#  define CMS_F_CMS_COPY_MESSAGEDIGEST                     108
+#  define CMS_F_CMS_DATA                                   109
+#  define CMS_F_CMS_DATAFINAL                              110
+#  define CMS_F_CMS_DATAINIT                               111
+#  define CMS_F_CMS_DECRYPT                                112
+#  define CMS_F_CMS_DECRYPT_SET1_KEY                       113
+#  define CMS_F_CMS_DECRYPT_SET1_PASSWORD                  166
+#  define CMS_F_CMS_DECRYPT_SET1_PKEY                      114
+#  define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX               115
+#  define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO               116
+#  define CMS_F_CMS_DIGESTEDDATA_DO_FINAL                  117
+#  define CMS_F_CMS_DIGEST_VERIFY                          118
+#  define CMS_F_CMS_ENCODE_RECEIPT                         161
+#  define CMS_F_CMS_ENCRYPT                                119
+#  define CMS_F_CMS_ENCRYPTEDCONTENT_INIT                  179
+#  define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO              120
+#  define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT                  121
+#  define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT                  122
+#  define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY                 123
+#  define CMS_F_CMS_ENVELOPEDDATA_CREATE                   124
+#  define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO                 125
+#  define CMS_F_CMS_ENVELOPED_DATA_INIT                    126
+#  define CMS_F_CMS_ENV_ASN1_CTRL                          171
+#  define CMS_F_CMS_FINAL                                  127
+#  define CMS_F_CMS_GET0_CERTIFICATE_CHOICES               128
+#  define CMS_F_CMS_GET0_CONTENT                           129
+#  define CMS_F_CMS_GET0_ECONTENT_TYPE                     130
+#  define CMS_F_CMS_GET0_ENVELOPED                         131
+#  define CMS_F_CMS_GET0_REVOCATION_CHOICES                132
+#  define CMS_F_CMS_GET0_SIGNED                            133
+#  define CMS_F_CMS_MSGSIGDIGEST_ADD1                      162
+#  define CMS_F_CMS_RECEIPTREQUEST_CREATE0                 159
+#  define CMS_F_CMS_RECEIPT_VERIFY                         160
+#  define CMS_F_CMS_RECIPIENTINFO_DECRYPT                  134
+#  define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                  169
+#  define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT             178
+#  define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG            175
+#  define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID        173
+#  define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS           172
+#  define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP         174
+#  define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT            135
+#  define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT            136
+#  define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID            137
+#  define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP             138
+#  define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP            139
+#  define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT             140
+#  define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT             141
+#  define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS           142
+#  define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID      143
+#  define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT               167
+#  define CMS_F_CMS_RECIPIENTINFO_SET0_KEY                 144
+#  define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD            168
+#  define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY                145
+#  define CMS_F_CMS_SD_ASN1_CTRL                           170
+#  define CMS_F_CMS_SET1_IAS                               176
+#  define CMS_F_CMS_SET1_KEYID                             177
+#  define CMS_F_CMS_SET1_SIGNERIDENTIFIER                  146
+#  define CMS_F_CMS_SET_DETACHED                           147
+#  define CMS_F_CMS_SIGN                                   148
+#  define CMS_F_CMS_SIGNED_DATA_INIT                       149
+#  define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN                150
+#  define CMS_F_CMS_SIGNERINFO_SIGN                        151
+#  define CMS_F_CMS_SIGNERINFO_VERIFY                      152
+#  define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
+#  define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
+#  define CMS_F_CMS_SIGN_RECEIPT                           163
+#  define CMS_F_CMS_SI_CHECK_ATTRIBUTES                    183
+#  define CMS_F_CMS_STREAM                                 155
+#  define CMS_F_CMS_UNCOMPRESS                             156
+#  define CMS_F_CMS_VERIFY                                 157
+#  define CMS_F_KEK_UNWRAP_KEY                             180
+
+/*
+ * CMS reason codes.
+ */
+#  define CMS_R_ADD_SIGNER_ERROR                           99
+#  define CMS_R_ATTRIBUTE_ERROR                            161
+#  define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
+#  define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
+#  define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
+#  define CMS_R_CIPHER_INITIALISATION_ERROR                101
+#  define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR      102
+#  define CMS_R_CMS_DATAFINAL_ERROR                        103
+#  define CMS_R_CMS_LIB                                    104
+#  define CMS_R_CONTENTIDENTIFIER_MISMATCH                 170
+#  define CMS_R_CONTENT_NOT_FOUND                          105
+#  define CMS_R_CONTENT_TYPE_MISMATCH                      171
+#  define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA           106
+#  define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA            107
+#  define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA               108
+#  define CMS_R_CONTENT_VERIFY_ERROR                       109
+#  define CMS_R_CTRL_ERROR                                 110
+#  define CMS_R_CTRL_FAILURE                               111
+#  define CMS_R_DECRYPT_ERROR                              112
+#  define CMS_R_ERROR_GETTING_PUBLIC_KEY                   113
+#  define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
+#  define CMS_R_ERROR_SETTING_KEY                          115
+#  define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
+#  define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
+#  define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
+#  define CMS_R_INVALID_KEY_LENGTH                         118
+#  define CMS_R_MD_BIO_INIT_ERROR                          119
+#  define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH       120
+#  define CMS_R_MESSAGEDIGEST_WRONG_LENGTH                 121
+#  define CMS_R_MSGSIGDIGEST_ERROR                         172
+#  define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE          162
+#  define CMS_R_MSGSIGDIGEST_WRONG_LENGTH                  163
+#  define CMS_R_NEED_ONE_SIGNER                            164
+#  define CMS_R_NOT_A_SIGNED_RECEIPT                       165
+#  define CMS_R_NOT_ENCRYPTED_DATA                         122
+#  define CMS_R_NOT_KEK                                    123
+#  define CMS_R_NOT_KEY_AGREEMENT                          181
+#  define CMS_R_NOT_KEY_TRANSPORT                          124
+#  define CMS_R_NOT_PWRI                                   177
+#  define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE            125
+#  define CMS_R_NO_CIPHER                                  126
+#  define CMS_R_NO_CONTENT                                 127
+#  define CMS_R_NO_CONTENT_TYPE                            173
+#  define CMS_R_NO_DEFAULT_DIGEST                          128
+#  define CMS_R_NO_DIGEST_SET                              129
+#  define CMS_R_NO_KEY                                     130
+#  define CMS_R_NO_KEY_OR_CERT                             174
+#  define CMS_R_NO_MATCHING_DIGEST                         131
+#  define CMS_R_NO_MATCHING_RECIPIENT                      132
+#  define CMS_R_NO_MATCHING_SIGNATURE                      166
+#  define CMS_R_NO_MSGSIGDIGEST                            167
+#  define CMS_R_NO_PASSWORD                                178
+#  define CMS_R_NO_PRIVATE_KEY                             133
+#  define CMS_R_NO_PUBLIC_KEY                              134
+#  define CMS_R_NO_RECEIPT_REQUEST                         168
+#  define CMS_R_NO_SIGNERS                                 135
+#  define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE     136
+#  define CMS_R_RECEIPT_DECODE_ERROR                       169
+#  define CMS_R_RECIPIENT_ERROR                            137
+#  define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND               138
+#  define CMS_R_SIGNFINAL_ERROR                            139
+#  define CMS_R_SMIME_TEXT_ERROR                           140
+#  define CMS_R_STORE_INIT_ERROR                           141
+#  define CMS_R_TYPE_NOT_COMPRESSED_DATA                   142
+#  define CMS_R_TYPE_NOT_DATA                              143
+#  define CMS_R_TYPE_NOT_DIGESTED_DATA                     144
+#  define CMS_R_TYPE_NOT_ENCRYPTED_DATA                    145
+#  define CMS_R_TYPE_NOT_ENVELOPED_DATA                    146
+#  define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                 147
+#  define CMS_R_UNKNOWN_CIPHER                             148
+#  define CMS_R_UNKNOWN_DIGEST_ALGORITHM                   149
+#  define CMS_R_UNKNOWN_ID                                 150
+#  define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM          151
+#  define CMS_R_UNSUPPORTED_CONTENT_TYPE                   152
+#  define CMS_R_UNSUPPORTED_KEK_ALGORITHM                  153
+#  define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM       179
+#  define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE             155
+#  define CMS_R_UNSUPPORTED_RECIPIENT_TYPE                 154
+#  define CMS_R_UNSUPPORTED_TYPE                           156
+#  define CMS_R_UNWRAP_ERROR                               157
+#  define CMS_R_UNWRAP_FAILURE                             180
+#  define CMS_R_VERIFICATION_FAILURE                       158
+#  define CMS_R_WRAP_ERROR                                 159
+
+# endif
+#endif

+ 53 - 0
rambus_sec_lib/include/openssl/comp.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_COMP_H
+# define HEADER_COMP_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_COMP
+# include <openssl/crypto.h>
+# include <openssl/comperr.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx);
+int COMP_CTX_get_type(const COMP_CTX* comp);
+int COMP_get_type(const COMP_METHOD *meth);
+const char *COMP_get_name(const COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                        unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                      unsigned char *in, int ilen);
+
+COMP_METHOD *COMP_zlib(void);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+#define COMP_zlib_cleanup() while(0) continue
+#endif
+
+# ifdef HEADER_BIO_H
+#  ifdef ZLIB
+const BIO_METHOD *BIO_f_zlib(void);
+#  endif
+# endif
+
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif

+ 44 - 0
rambus_sec_lib/include/openssl/comperr.h

@@ -0,0 +1,44 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_COMPERR_H
+# define HEADER_COMPERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_COMP
+
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+int ERR_load_COMP_strings(void);
+
+/*
+ * COMP function codes.
+ */
+#  define COMP_F_BIO_ZLIB_FLUSH                            99
+#  define COMP_F_BIO_ZLIB_NEW                              100
+#  define COMP_F_BIO_ZLIB_READ                             101
+#  define COMP_F_BIO_ZLIB_WRITE                            102
+#  define COMP_F_COMP_CTX_NEW                              103
+
+/*
+ * COMP reason codes.
+ */
+#  define COMP_R_ZLIB_DEFLATE_ERROR                        99
+#  define COMP_R_ZLIB_INFLATE_ERROR                        100
+#  define COMP_R_ZLIB_NOT_SUPPORTED                        101
+
+# endif
+#endif

+ 168 - 0
rambus_sec_lib/include/openssl/conf.h

@@ -0,0 +1,168 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef  HEADER_CONF_H
+# define HEADER_CONF_H
+
+# include <openssl/bio.h>
+# include <openssl/lhash.h>
+# include <openssl/safestack.h>
+# include <openssl/e_os2.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/conferr.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    char *section;
+    char *name;
+    char *value;
+} CONF_VALUE;
+
+DEFINE_STACK_OF(CONF_VALUE)
+DEFINE_LHASH_OF(CONF_VALUE);
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st {
+    const char *name;
+    CONF *(*create) (CONF_METHOD *meth);
+    int (*init) (CONF *conf);
+    int (*destroy) (CONF *conf);
+    int (*destroy_data) (CONF *conf);
+    int (*load_bio) (CONF *conf, BIO *bp, long *eline);
+    int (*dump) (const CONF *conf, BIO *bp);
+    int (*is_number) (const CONF *conf, char c);
+    int (*to_int) (const CONF *conf, char c);
+    int (*load) (CONF *conf, const char *name, long *eline);
+};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+DEFINE_STACK_OF(CONF_MODULE)
+DEFINE_STACK_OF(CONF_IMODULE)
+
+/* DSO module function typedefs */
+typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func (CONF_IMODULE *md);
+
+# define CONF_MFLAGS_IGNORE_ERRORS       0x1
+# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2
+# define CONF_MFLAGS_SILENT              0x4
+# define CONF_MFLAGS_NO_DSO              0x8
+# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+# define CONF_MFLAGS_DEFAULT_SECTION     0x20
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash);
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+                                long *eline);
+# ifndef OPENSSL_NO_STDIO
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+                                   long *eline);
+# endif
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+                                    long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+                                       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+#ifndef OPENSSL_NO_STDIO
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+#endif
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
+
+DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name))
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define OPENSSL_no_config() \
+    OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL)
+#endif
+
+/*
+ * New conf code.  The semantics are different from the functions above. If
+ * that wasn't the case, the above functions would have been replaced
+ */
+
+struct conf_st {
+    CONF_METHOD *meth;
+    void *meth_data;
+    LHASH_OF(CONF_VALUE) *data;
+};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+int NCONF_load(CONF *conf, const char *file, long *eline);
+# ifndef OPENSSL_NO_STDIO
+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline);
+# endif
+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
+                                        const char *section);
+char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+                       long *result);
+#ifndef OPENSSL_NO_STDIO
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+#endif
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+                      unsigned long flags);
+int CONF_modules_load_file(const char *filename, const char *appname,
+                           unsigned long flags);
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define CONF_modules_free() while(0) continue
+#endif
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+                    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+                    int (*list_cb) (const char *elem, int len, void *usr),
+                    void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 40 - 0
rambus_sec_lib/include/openssl/conf_api.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef  HEADER_CONF_API_H
+# define HEADER_CONF_API_H
+
+# include <openssl/lhash.h>
+# include <openssl/conf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+                                               const char *section);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+                       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section,
+                      const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif

+ 76 - 0
rambus_sec_lib/include/openssl/conferr.h

@@ -0,0 +1,76 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CONFERR_H
+# define HEADER_CONFERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_CONF_strings(void);
+
+/*
+ * CONF function codes.
+ */
+# define CONF_F_CONF_DUMP_FP                              104
+# define CONF_F_CONF_LOAD                                 100
+# define CONF_F_CONF_LOAD_FP                              103
+# define CONF_F_CONF_PARSE_LIST                           119
+# define CONF_F_DEF_LOAD                                  120
+# define CONF_F_DEF_LOAD_BIO                              121
+# define CONF_F_GET_NEXT_FILE                             107
+# define CONF_F_MODULE_ADD                                122
+# define CONF_F_MODULE_INIT                               115
+# define CONF_F_MODULE_LOAD_DSO                           117
+# define CONF_F_MODULE_RUN                                118
+# define CONF_F_NCONF_DUMP_BIO                            105
+# define CONF_F_NCONF_DUMP_FP                             106
+# define CONF_F_NCONF_GET_NUMBER_E                        112
+# define CONF_F_NCONF_GET_SECTION                         108
+# define CONF_F_NCONF_GET_STRING                          109
+# define CONF_F_NCONF_LOAD                                113
+# define CONF_F_NCONF_LOAD_BIO                            110
+# define CONF_F_NCONF_LOAD_FP                             114
+# define CONF_F_NCONF_NEW                                 111
+# define CONF_F_PROCESS_INCLUDE                           116
+# define CONF_F_SSL_MODULE_INIT                           123
+# define CONF_F_STR_COPY                                  101
+
+/*
+ * CONF reason codes.
+ */
+# define CONF_R_ERROR_LOADING_DSO                         110
+# define CONF_R_LIST_CANNOT_BE_NULL                       115
+# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET              100
+# define CONF_R_MISSING_EQUAL_SIGN                        101
+# define CONF_R_MISSING_INIT_FUNCTION                     112
+# define CONF_R_MODULE_INITIALIZATION_ERROR               109
+# define CONF_R_NO_CLOSE_BRACE                            102
+# define CONF_R_NO_CONF                                   105
+# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE           106
+# define CONF_R_NO_SECTION                                107
+# define CONF_R_NO_SUCH_FILE                              114
+# define CONF_R_NO_VALUE                                  108
+# define CONF_R_NUMBER_TOO_LARGE                          121
+# define CONF_R_RECURSIVE_DIRECTORY_INCLUDE               111
+# define CONF_R_SSL_COMMAND_SECTION_EMPTY                 117
+# define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND             118
+# define CONF_R_SSL_SECTION_EMPTY                         119
+# define CONF_R_SSL_SECTION_NOT_FOUND                     120
+# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION              103
+# define CONF_R_UNKNOWN_MODULE_NAME                       113
+# define CONF_R_VARIABLE_EXPANSION_TOO_LONG               116
+# define CONF_R_VARIABLE_HAS_NO_VALUE                     104
+
+#endif

+ 445 - 0
rambus_sec_lib/include/openssl/crypto.h

@@ -0,0 +1,445 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CRYPTO_H
+# define HEADER_CRYPTO_H
+
+# include <stdlib.h>
+# include <time.h>
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+
+# include <openssl/safestack.h>
+# include <openssl/opensslv.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/opensslconf.h>
+# include <openssl/cryptoerr.h>
+
+# ifdef CHARSET_EBCDIC
+#  include <openssl/ebcdic.h>
+# endif
+
+/*
+ * Resolve problems on some operating systems with symbol names that clash
+ * one way or another
+ */
+# include <openssl/symhacks.h>
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/opensslv.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define SSLeay                  OpenSSL_version_num
+#  define SSLeay_version          OpenSSL_version
+#  define SSLEAY_VERSION_NUMBER   OPENSSL_VERSION_NUMBER
+#  define SSLEAY_VERSION          OPENSSL_VERSION
+#  define SSLEAY_CFLAGS           OPENSSL_CFLAGS
+#  define SSLEAY_BUILT_ON         OPENSSL_BUILT_ON
+#  define SSLEAY_PLATFORM         OPENSSL_PLATFORM
+#  define SSLEAY_DIR              OPENSSL_DIR
+
+/*
+ * Old type for allocating dynamic locks. No longer used. Use the new thread
+ * API instead.
+ */
+typedef struct {
+    int dummy;
+} CRYPTO_dynlock;
+
+# endif /* OPENSSL_API_COMPAT */
+
+typedef void CRYPTO_RWLOCK;
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock);
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
+
+/*
+ * The following can be used to detect memory leaks in the library. If
+ * used, it turns on malloc checking
+ */
+# define CRYPTO_MEM_CHECK_OFF     0x0   /* Control only */
+# define CRYPTO_MEM_CHECK_ON      0x1   /* Control and mode bit */
+# define CRYPTO_MEM_CHECK_ENABLE  0x2   /* Control and mode bit */
+# define CRYPTO_MEM_CHECK_DISABLE 0x3   /* Control only */
+
+struct crypto_ex_data_st {
+    STACK_OF(void) *sk;
+};
+DEFINE_STACK_OF(void)
+
+/*
+ * Per class, we have a STACK of function pointers.
+ */
+# define CRYPTO_EX_INDEX_SSL              0
+# define CRYPTO_EX_INDEX_SSL_CTX          1
+# define CRYPTO_EX_INDEX_SSL_SESSION      2
+# define CRYPTO_EX_INDEX_X509             3
+# define CRYPTO_EX_INDEX_X509_STORE       4
+# define CRYPTO_EX_INDEX_X509_STORE_CTX   5
+# define CRYPTO_EX_INDEX_DH               6
+# define CRYPTO_EX_INDEX_DSA              7
+# define CRYPTO_EX_INDEX_EC_KEY           8
+# define CRYPTO_EX_INDEX_RSA              9
+# define CRYPTO_EX_INDEX_ENGINE          10
+# define CRYPTO_EX_INDEX_UI              11
+# define CRYPTO_EX_INDEX_BIO             12
+# define CRYPTO_EX_INDEX_APP             13
+# define CRYPTO_EX_INDEX_UI_METHOD       14
+# define CRYPTO_EX_INDEX_DRBG            15
+# define CRYPTO_EX_INDEX__COUNT          16
+
+/* No longer needed, so this is a no-op */
+#define OPENSSL_malloc_init() while(0) continue
+
+int CRYPTO_mem_ctrl(int mode);
+
+# define OPENSSL_malloc(num) \
+        CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_zalloc(num) \
+        CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_realloc(addr, num) \
+        CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_clear_realloc(addr, old_num, num) \
+        CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_clear_free(addr, num) \
+        CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_free(addr) \
+        CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_memdup(str, s) \
+        CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_strdup(str) \
+        CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_strndup(str, n) \
+        CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_malloc(num) \
+        CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_zalloc(num) \
+        CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_free(addr) \
+        CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_clear_free(addr, num) \
+        CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_actual_size(ptr) \
+        CRYPTO_secure_actual_size(ptr)
+
+size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz);
+size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz);
+size_t OPENSSL_strnlen(const char *str, size_t maxlen);
+char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len);
+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len);
+int OPENSSL_hexchar2int(unsigned char c);
+
+# define OPENSSL_MALLOC_MAX_NELEMS(type)  (((1U<<(sizeof(int)*8-1))-1)/sizeof(type))
+
+unsigned long OpenSSL_version_num(void);
+const char *OpenSSL_version(int type);
+# define OPENSSL_VERSION          0
+# define OPENSSL_CFLAGS           1
+# define OPENSSL_BUILT_ON         2
+# define OPENSSL_PLATFORM         3
+# define OPENSSL_DIR              4
+# define OPENSSL_ENGINES_DIR      5
+
+int OPENSSL_issetugid(void);
+
+typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                           int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                             int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+                           void *from_d, int idx, long argl, void *argp);
+__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+                            CRYPTO_EX_free *free_func);
+/* No longer use an index. */
+int CRYPTO_free_ex_index(int class_index, int idx);
+
+/*
+ * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a
+ * given class (invokes whatever per-class callbacks are applicable)
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+                       const CRYPTO_EX_DATA *from);
+
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+
+/*
+ * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular
+ * index (relative to the class type involved)
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions.
+ */
+# define CRYPTO_cleanup_all_ex_data() while(0) continue
+
+/*
+ * The old locking functions have been removed completely without compatibility
+ * macros. This is because the old functions either could not properly report
+ * errors, or the returned error values were not clearly documented.
+ * Replacing the locking functions with no-ops would cause race condition
+ * issues in the affected applications. It is far better for them to fail at
+ * compile time.
+ * On the other hand, the locking callbacks are no longer used.  Consequently,
+ * the callback management functions can be safely replaced with no-op macros.
+ */
+#  define CRYPTO_num_locks()            (1)
+#  define CRYPTO_set_locking_callback(func)
+#  define CRYPTO_get_locking_callback()         (NULL)
+#  define CRYPTO_set_add_lock_callback(func)
+#  define CRYPTO_get_add_lock_callback()        (NULL)
+
+/*
+ * These defines where used in combination with the old locking callbacks,
+ * they are not called anymore, but old code that's not called might still
+ * use them.
+ */
+#  define CRYPTO_LOCK             1
+#  define CRYPTO_UNLOCK           2
+#  define CRYPTO_READ             4
+#  define CRYPTO_WRITE            8
+
+/* This structure is no longer used */
+typedef struct crypto_threadid_st {
+    int dummy;
+} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+#  define CRYPTO_THREADID_set_numeric(id, val)
+#  define CRYPTO_THREADID_set_pointer(id, ptr)
+#  define CRYPTO_THREADID_set_callback(threadid_func)   (0)
+#  define CRYPTO_THREADID_get_callback()                (NULL)
+#  define CRYPTO_THREADID_current(id)
+#  define CRYPTO_THREADID_cmp(a, b)                     (-1)
+#  define CRYPTO_THREADID_cpy(dest, src)
+#  define CRYPTO_THREADID_hash(id)                      (0UL)
+
+#  if OPENSSL_API_COMPAT < 0x10000000L
+#   define CRYPTO_set_id_callback(func)
+#   define CRYPTO_get_id_callback()                     (NULL)
+#   define CRYPTO_thread_id()                           (0UL)
+#  endif /* OPENSSL_API_COMPAT < 0x10000000L */
+
+#  define CRYPTO_set_dynlock_create_callback(dyn_create_function)
+#  define CRYPTO_set_dynlock_lock_callback(dyn_lock_function)
+#  define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function)
+#  define CRYPTO_get_dynlock_create_callback()          (NULL)
+#  define CRYPTO_get_dynlock_lock_callback()            (NULL)
+#  define CRYPTO_get_dynlock_destroy_callback()         (NULL)
+# endif /* OPENSSL_API_COMPAT < 0x10100000L */
+
+int CRYPTO_set_mem_functions(
+        void *(*m) (size_t, const char *, int),
+        void *(*r) (void *, size_t, const char *, int),
+        void (*f) (void *, const char *, int));
+int CRYPTO_set_mem_debug(int flag);
+void CRYPTO_get_mem_functions(
+        void *(**m) (size_t, const char *, int),
+        void *(**r) (void *, size_t, const char *, int),
+        void (**f) (void *, const char *, int));
+
+void *CRYPTO_malloc(size_t num, const char *file, int line);
+void *CRYPTO_zalloc(size_t num, const char *file, int line);
+void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
+char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line);
+void CRYPTO_free(void *ptr, const char *file, int line);
+void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line);
+void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line);
+void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
+                           const char *file, int line);
+
+int CRYPTO_secure_malloc_init(size_t sz, int minsize);
+int CRYPTO_secure_malloc_done(void);
+void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
+void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
+void CRYPTO_secure_free(void *ptr, const char *file, int line);
+void CRYPTO_secure_clear_free(void *ptr, size_t num,
+                              const char *file, int line);
+int CRYPTO_secure_allocated(const void *ptr);
+int CRYPTO_secure_malloc_initialized(void);
+size_t CRYPTO_secure_actual_size(void *ptr);
+size_t CRYPTO_secure_used(void);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+# ifndef OPENSSL_NO_CRYPTO_MDEBUG
+#  define OPENSSL_mem_debug_push(info) \
+        CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE)
+#  define OPENSSL_mem_debug_pop() \
+        CRYPTO_mem_debug_pop()
+int CRYPTO_mem_debug_push(const char *info, const char *file, int line);
+int CRYPTO_mem_debug_pop(void);
+void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount);
+
+/*-
+ * Debugging functions (enabled by CRYPTO_set_mem_debug(1))
+ * The flag argument has the following significance:
+ *   0:   called before the actual memory allocation has taken place
+ *   1:   called after the actual memory allocation has taken place
+ */
+void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag,
+        const char *file, int line);
+void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag,
+        const char *file, int line);
+void CRYPTO_mem_debug_free(void *addr, int flag,
+        const char *file, int line);
+
+int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u),
+                        void *u);
+#  ifndef OPENSSL_NO_STDIO
+int CRYPTO_mem_leaks_fp(FILE *);
+#  endif
+int CRYPTO_mem_leaks(BIO *bio);
+# endif
+
+/* die if we have to */
+ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line);
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l))
+# endif
+# define OPENSSL_assert(e) \
+    (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1))
+
+int OPENSSL_isservice(void);
+
+int FIPS_mode(void);
+int FIPS_mode_set(int r);
+
+void OPENSSL_init(void);
+# ifdef OPENSSL_SYS_UNIX
+void OPENSSL_fork_prepare(void);
+void OPENSSL_fork_parent(void);
+void OPENSSL_fork_child(void);
+# endif
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
+int OPENSSL_gmtime_diff(int *pday, int *psec,
+                        const struct tm *from, const struct tm *to);
+
+/*
+ * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal.
+ * It takes an amount of time dependent on |len|, but independent of the
+ * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements
+ * into a defined order as the return value when a != b is undefined, other
+ * than to be non-zero.
+ */
+int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
+
+/* Standard initialisation options */
+# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L
+# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS    0x00000002L
+# define OPENSSL_INIT_ADD_ALL_CIPHERS        0x00000004L
+# define OPENSSL_INIT_ADD_ALL_DIGESTS        0x00000008L
+# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS     0x00000010L
+# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS     0x00000020L
+# define OPENSSL_INIT_LOAD_CONFIG            0x00000040L
+# define OPENSSL_INIT_NO_LOAD_CONFIG         0x00000080L
+# define OPENSSL_INIT_ASYNC                  0x00000100L
+# define OPENSSL_INIT_ENGINE_RDRAND          0x00000200L
+# define OPENSSL_INIT_ENGINE_DYNAMIC         0x00000400L
+# define OPENSSL_INIT_ENGINE_OPENSSL         0x00000800L
+# define OPENSSL_INIT_ENGINE_CRYPTODEV       0x00001000L
+# define OPENSSL_INIT_ENGINE_CAPI            0x00002000L
+# define OPENSSL_INIT_ENGINE_PADLOCK         0x00004000L
+# define OPENSSL_INIT_ENGINE_AFALG           0x00008000L
+/* OPENSSL_INIT_ZLIB                         0x00010000L */
+# define OPENSSL_INIT_ATFORK                 0x00020000L
+/* OPENSSL_INIT_BASE_ONLY                    0x00040000L */
+# define OPENSSL_INIT_NO_ATEXIT              0x00080000L
+/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */
+/* Max OPENSSL_INIT flag value is 0x80000000 */
+
+/* openssl and dasync not counted as builtin */
+# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \
+    (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \
+    | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \
+    OPENSSL_INIT_ENGINE_PADLOCK)
+
+
+/* Library initialisation functions */
+void OPENSSL_cleanup(void);
+int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+int OPENSSL_atexit(void (*handler)(void));
+void OPENSSL_thread_stop(void);
+
+/* Low-level control of initialization */
+OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void);
+# ifndef OPENSSL_NO_STDIO
+int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings,
+                                     const char *config_filename);
+void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings,
+                                        unsigned long flags);
+int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings,
+                                    const char *config_appname);
+# endif
+void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings);
+
+# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+#  if defined(_WIN32)
+#   if defined(BASETYPES) || defined(_WINDEF_H)
+/* application has to include <windows.h> in order to use this */
+typedef DWORD CRYPTO_THREAD_LOCAL;
+typedef DWORD CRYPTO_THREAD_ID;
+
+typedef LONG CRYPTO_ONCE;
+#    define CRYPTO_ONCE_STATIC_INIT 0
+#   endif
+#  else
+#   include <pthread.h>
+typedef pthread_once_t CRYPTO_ONCE;
+typedef pthread_key_t CRYPTO_THREAD_LOCAL;
+typedef pthread_t CRYPTO_THREAD_ID;
+
+#   define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT
+#  endif
+# endif
+
+# if !defined(CRYPTO_ONCE_STATIC_INIT)
+typedef unsigned int CRYPTO_ONCE;
+typedef unsigned int CRYPTO_THREAD_LOCAL;
+typedef unsigned int CRYPTO_THREAD_ID;
+#  define CRYPTO_ONCE_STATIC_INIT 0
+# endif
+
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *));
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key);
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val);
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key);
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void);
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b);
+
+
+# ifdef  __cplusplus
+}
+# endif
+#endif

+ 57 - 0
rambus_sec_lib/include/openssl/cryptoerr.h

@@ -0,0 +1,57 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CRYPTOERR_H
+# define HEADER_CRYPTOERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C"
+# endif
+int ERR_load_CRYPTO_strings(void);
+
+/*
+ * CRYPTO function codes.
+ */
+# define CRYPTO_F_CMAC_CTX_NEW                            120
+# define CRYPTO_F_CRYPTO_DUP_EX_DATA                      110
+# define CRYPTO_F_CRYPTO_FREE_EX_DATA                     111
+# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX                 100
+# define CRYPTO_F_CRYPTO_MEMDUP                           115
+# define CRYPTO_F_CRYPTO_NEW_EX_DATA                      112
+# define CRYPTO_F_CRYPTO_OCB128_COPY_CTX                  121
+# define CRYPTO_F_CRYPTO_OCB128_INIT                      122
+# define CRYPTO_F_CRYPTO_SET_EX_DATA                      102
+# define CRYPTO_F_FIPS_MODE_SET                           109
+# define CRYPTO_F_GET_AND_LOCK                            113
+# define CRYPTO_F_OPENSSL_ATEXIT                          114
+# define CRYPTO_F_OPENSSL_BUF2HEXSTR                      117
+# define CRYPTO_F_OPENSSL_FOPEN                           119
+# define CRYPTO_F_OPENSSL_HEXSTR2BUF                      118
+# define CRYPTO_F_OPENSSL_INIT_CRYPTO                     116
+# define CRYPTO_F_OPENSSL_LH_NEW                          126
+# define CRYPTO_F_OPENSSL_SK_DEEP_COPY                    127
+# define CRYPTO_F_OPENSSL_SK_DUP                          128
+# define CRYPTO_F_PKEY_HMAC_INIT                          123
+# define CRYPTO_F_PKEY_POLY1305_INIT                      124
+# define CRYPTO_F_PKEY_SIPHASH_INIT                       125
+# define CRYPTO_F_SK_RESERVE                              129
+
+/*
+ * CRYPTO reason codes.
+ */
+# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                 101
+# define CRYPTO_R_ILLEGAL_HEX_DIGIT                       102
+# define CRYPTO_R_ODD_NUMBER_OF_DIGITS                    103
+
+#endif

+ 474 - 0
rambus_sec_lib/include/openssl/ct.h

@@ -0,0 +1,474 @@
+/*
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CT_H
+# define HEADER_CT_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CT
+# include <openssl/ossl_typ.h>
+# include <openssl/safestack.h>
+# include <openssl/x509.h>
+# include <openssl/cterr.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+
+/* Minimum RSA key size, from RFC6962 */
+# define SCT_MIN_RSA_BITS 2048
+
+/* All hashes are SHA256 in v1 of Certificate Transparency */
+# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH
+
+typedef enum {
+    CT_LOG_ENTRY_TYPE_NOT_SET = -1,
+    CT_LOG_ENTRY_TYPE_X509 = 0,
+    CT_LOG_ENTRY_TYPE_PRECERT = 1
+} ct_log_entry_type_t;
+
+typedef enum {
+    SCT_VERSION_NOT_SET = -1,
+    SCT_VERSION_V1 = 0
+} sct_version_t;
+
+typedef enum {
+    SCT_SOURCE_UNKNOWN,
+    SCT_SOURCE_TLS_EXTENSION,
+    SCT_SOURCE_X509V3_EXTENSION,
+    SCT_SOURCE_OCSP_STAPLED_RESPONSE
+} sct_source_t;
+
+typedef enum {
+    SCT_VALIDATION_STATUS_NOT_SET,
+    SCT_VALIDATION_STATUS_UNKNOWN_LOG,
+    SCT_VALIDATION_STATUS_VALID,
+    SCT_VALIDATION_STATUS_INVALID,
+    SCT_VALIDATION_STATUS_UNVERIFIED,
+    SCT_VALIDATION_STATUS_UNKNOWN_VERSION
+} sct_validation_status_t;
+
+DEFINE_STACK_OF(SCT)
+DEFINE_STACK_OF(CTLOG)
+
+/******************************************
+ * CT policy evaluation context functions *
+ ******************************************/
+
+/*
+ * Creates a new, empty policy evaluation context.
+ * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished
+ * with the CT_POLICY_EVAL_CTX.
+ */
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void);
+
+/* Deletes a policy evaluation context and anything it owns. */
+void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx);
+
+/* Gets the peer certificate that the SCTs are for */
+X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the certificate associated with the received SCTs.
+ * Increments the reference count of cert.
+ * Returns 1 on success, 0 otherwise.
+ */
+int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert);
+
+/* Gets the issuer of the aforementioned certificate */
+X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the issuer of the certificate associated with the received SCTs.
+ * Increments the reference count of issuer.
+ * Returns 1 on success, 0 otherwise.
+ */
+int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer);
+
+/* Gets the CT logs that are trusted sources of SCTs */
+const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx);
+
+/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */
+void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
+                                               CTLOG_STORE *log_store);
+
+/*
+ * Gets the time, in milliseconds since the Unix epoch, that will be used as the
+ * current time when checking whether an SCT was issued in the future.
+ * Such SCTs will fail validation, as required by RFC6962.
+ */
+uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch.
+ * If an SCT's timestamp is after this time, it will be interpreted as having
+ * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs
+ * whose timestamp is in the future", so an SCT will not validate in this case.
+ */
+void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms);
+
+/*****************
+ * SCT functions *
+ *****************/
+
+/*
+ * Creates a new, blank SCT.
+ * The caller is responsible for calling SCT_free when finished with the SCT.
+ */
+SCT *SCT_new(void);
+
+/*
+ * Creates a new SCT from some base64-encoded strings.
+ * The caller is responsible for calling SCT_free when finished with the SCT.
+ */
+SCT *SCT_new_from_base64(unsigned char version,
+                         const char *logid_base64,
+                         ct_log_entry_type_t entry_type,
+                         uint64_t timestamp,
+                         const char *extensions_base64,
+                         const char *signature_base64);
+
+/*
+ * Frees the SCT and the underlying data structures.
+ */
+void SCT_free(SCT *sct);
+
+/*
+ * Free a stack of SCTs, and the underlying SCTs themselves.
+ * Intended to be compatible with X509V3_EXT_FREE.
+ */
+void SCT_LIST_free(STACK_OF(SCT) *a);
+
+/*
+ * Returns the version of the SCT.
+ */
+sct_version_t SCT_get_version(const SCT *sct);
+
+/*
+ * Set the version of an SCT.
+ * Returns 1 on success, 0 if the version is unrecognized.
+ */
+__owur int SCT_set_version(SCT *sct, sct_version_t version);
+
+/*
+ * Returns the log entry type of the SCT.
+ */
+ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct);
+
+/*
+ * Set the log entry type of an SCT.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type);
+
+/*
+ * Gets the ID of the log that an SCT came from.
+ * Ownership of the log ID remains with the SCT.
+ * Returns the length of the log ID.
+ */
+size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id);
+
+/*
+ * Set the log ID of an SCT to point directly to the *log_id specified.
+ * The SCT takes ownership of the specified pointer.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len);
+
+/*
+ * Set the log ID of an SCT.
+ * This makes a copy of the log_id.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id,
+                           size_t log_id_len);
+
+/*
+ * Returns the timestamp for the SCT (epoch time in milliseconds).
+ */
+uint64_t SCT_get_timestamp(const SCT *sct);
+
+/*
+ * Set the timestamp of an SCT (epoch time in milliseconds).
+ */
+void SCT_set_timestamp(SCT *sct, uint64_t timestamp);
+
+/*
+ * Return the NID for the signature used by the SCT.
+ * For CT v1, this will be either NID_sha256WithRSAEncryption or
+ * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset).
+ */
+int SCT_get_signature_nid(const SCT *sct);
+
+/*
+ * Set the signature type of an SCT
+ * For CT v1, this should be either NID_sha256WithRSAEncryption or
+ * NID_ecdsa_with_SHA256.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_signature_nid(SCT *sct, int nid);
+
+/*
+ * Set *ext to point to the extension data for the SCT. ext must not be NULL.
+ * The SCT retains ownership of this pointer.
+ * Returns length of the data pointed to.
+ */
+size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext);
+
+/*
+ * Set the extensions of an SCT to point directly to the *ext specified.
+ * The SCT takes ownership of the specified pointer.
+ */
+void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len);
+
+/*
+ * Set the extensions of an SCT.
+ * This takes a copy of the ext.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext,
+                               size_t ext_len);
+
+/*
+ * Set *sig to point to the signature for the SCT. sig must not be NULL.
+ * The SCT retains ownership of this pointer.
+ * Returns length of the data pointed to.
+ */
+size_t SCT_get0_signature(const SCT *sct, unsigned char **sig);
+
+/*
+ * Set the signature of an SCT to point directly to the *sig specified.
+ * The SCT takes ownership of the specified pointer.
+ */
+void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len);
+
+/*
+ * Set the signature of an SCT to be a copy of the *sig specified.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig,
+                              size_t sig_len);
+
+/*
+ * The origin of this SCT, e.g. TLS extension, OCSP response, etc.
+ */
+sct_source_t SCT_get_source(const SCT *sct);
+
+/*
+ * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_source(SCT *sct, sct_source_t source);
+
+/*
+ * Returns a text string describing the validation status of |sct|.
+ */
+const char *SCT_validation_status_string(const SCT *sct);
+
+/*
+ * Pretty-prints an |sct| to |out|.
+ * It will be indented by the number of spaces specified by |indent|.
+ * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came
+ * from, so that the log name can be printed.
+ */
+void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs);
+
+/*
+ * Pretty-prints an |sct_list| to |out|.
+ * It will be indented by the number of spaces specified by |indent|.
+ * SCTs will be delimited by |separator|.
+ * If |logs| is not NULL, it will be used to lookup the CT log that each SCT
+ * came from, so that the log names can be printed.
+ */
+void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
+                    const char *separator, const CTLOG_STORE *logs);
+
+/*
+ * Gets the last result of validating this SCT.
+ * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET.
+ */
+sct_validation_status_t SCT_get_validation_status(const SCT *sct);
+
+/*
+ * Validates the given SCT with the provided context.
+ * Sets the "validation_status" field of the SCT.
+ * Returns 1 if the SCT is valid and the signature verifies.
+ * Returns 0 if the SCT is invalid or could not be verified.
+ * Returns -1 if an error occurs.
+ */
+__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Validates the given list of SCTs with the provided context.
+ * Sets the "validation_status" field of each SCT.
+ * Returns 1 if there are no invalid SCTs and all signatures verify.
+ * Returns 0 if at least one SCT is invalid or could not be verified.
+ * Returns a negative integer if an error occurs.
+ */
+__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts,
+                             CT_POLICY_EVAL_CTX *ctx);
+
+
+/*********************************
+ * SCT parsing and serialisation *
+ *********************************/
+
+/*
+ * Serialize (to TLS format) a stack of SCTs and return the length.
+ * "a" must not be NULL.
+ * If "pp" is NULL, just return the length of what would have been serialized.
+ * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer
+ * for data that caller is responsible for freeing (only if function returns
+ * successfully).
+ * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring
+ * that "*pp" is large enough to accept all of the serialized data.
+ * Returns < 0 on error, >= 0 indicating bytes written (or would have been)
+ * on success.
+ */
+__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp);
+
+/*
+ * Convert TLS format SCT list to a stack of SCTs.
+ * If "a" or "*a" is NULL, a new stack will be created that the caller is
+ * responsible for freeing (by calling SCT_LIST_free).
+ * "**pp" and "*pp" must not be NULL.
+ * Upon success, "*pp" will point to after the last bytes read, and a stack
+ * will be returned.
+ * Upon failure, a NULL pointer will be returned, and the position of "*pp" is
+ * not defined.
+ */
+STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            size_t len);
+
+/*
+ * Serialize (to DER format) a stack of SCTs and return the length.
+ * "a" must not be NULL.
+ * If "pp" is NULL, just returns the length of what would have been serialized.
+ * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer
+ * for data that caller is responsible for freeing (only if function returns
+ * successfully).
+ * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring
+ * that "*pp" is large enough to accept all of the serialized data.
+ * Returns < 0 on error, >= 0 indicating bytes written (or would have been)
+ * on success.
+ */
+__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp);
+
+/*
+ * Parses an SCT list in DER format and returns it.
+ * If "a" or "*a" is NULL, a new stack will be created that the caller is
+ * responsible for freeing (by calling SCT_LIST_free).
+ * "**pp" and "*pp" must not be NULL.
+ * Upon success, "*pp" will point to after the last bytes read, and a stack
+ * will be returned.
+ * Upon failure, a NULL pointer will be returned, and the position of "*pp" is
+ * not defined.
+ */
+STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            long len);
+
+/*
+ * Serialize (to TLS format) an |sct| and write it to |out|.
+ * If |out| is null, no SCT will be output but the length will still be returned.
+ * If |out| points to a null pointer, a string will be allocated to hold the
+ * TLS-format SCT. It is the responsibility of the caller to free it.
+ * If |out| points to an allocated string, the TLS-format SCT will be written
+ * to it.
+ * The length of the SCT in TLS format will be returned.
+ */
+__owur int i2o_SCT(const SCT *sct, unsigned char **out);
+
+/*
+ * Parses an SCT in TLS format and returns it.
+ * If |psct| is not null, it will end up pointing to the parsed SCT. If it
+ * already points to a non-null pointer, the pointer will be free'd.
+ * |in| should be a pointer to a string containing the TLS-format SCT.
+ * |in| will be advanced to the end of the SCT if parsing succeeds.
+ * |len| should be the length of the SCT in |in|.
+ * Returns NULL if an error occurs.
+ * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len'
+ * fields will be populated (with |in| and |len| respectively).
+ */
+SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len);
+
+/********************
+ * CT log functions *
+ ********************/
+
+/*
+ * Creates a new CT log instance with the given |public_key| and |name|.
+ * Takes ownership of |public_key| but copies |name|.
+ * Returns NULL if malloc fails or if |public_key| cannot be converted to DER.
+ * Should be deleted by the caller using CTLOG_free when no longer needed.
+ */
+CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name);
+
+/*
+ * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER
+ * in |pkey_base64|. The |name| is a string to help users identify this log.
+ * Returns 1 on success, 0 on failure.
+ * Should be deleted by the caller using CTLOG_free when no longer needed.
+ */
+int CTLOG_new_from_base64(CTLOG ** ct_log,
+                          const char *pkey_base64, const char *name);
+
+/*
+ * Deletes a CT log instance and its fields.
+ */
+void CTLOG_free(CTLOG *log);
+
+/* Gets the name of the CT log */
+const char *CTLOG_get0_name(const CTLOG *log);
+/* Gets the ID of the CT log */
+void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
+                       size_t *log_id_len);
+/* Gets the public key of the CT log */
+EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log);
+
+/**************************
+ * CT log store functions *
+ **************************/
+
+/*
+ * Creates a new CT log store.
+ * Should be deleted by the caller using CTLOG_STORE_free when no longer needed.
+ */
+CTLOG_STORE *CTLOG_STORE_new(void);
+
+/*
+ * Deletes a CT log store and all of the CT log instances held within.
+ */
+void CTLOG_STORE_free(CTLOG_STORE *store);
+
+/*
+ * Finds a CT log in the store based on its log ID.
+ * Returns the CT log, or NULL if no match is found.
+ */
+const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
+                                        const uint8_t *log_id,
+                                        size_t log_id_len);
+
+/*
+ * Loads a CT log list into a |store| from a |file|.
+ * Returns 1 if loading is successful, or 0 otherwise.
+ */
+__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file);
+
+/*
+ * Loads the default CT log list into a |store|.
+ * Returns 1 if loading is successful, or 0 otherwise.
+ */
+__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store);
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif

+ 80 - 0
rambus_sec_lib/include/openssl/cterr.h

@@ -0,0 +1,80 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_CTERR_H
+# define HEADER_CTERR_H
+
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CT
+
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+int ERR_load_CT_strings(void);
+
+/*
+ * CT function codes.
+ */
+#  define CT_F_CTLOG_NEW                                   117
+#  define CT_F_CTLOG_NEW_FROM_BASE64                       118
+#  define CT_F_CTLOG_NEW_FROM_CONF                         119
+#  define CT_F_CTLOG_STORE_LOAD_CTX_NEW                    122
+#  define CT_F_CTLOG_STORE_LOAD_FILE                       123
+#  define CT_F_CTLOG_STORE_LOAD_LOG                        130
+#  define CT_F_CTLOG_STORE_NEW                             131
+#  define CT_F_CT_BASE64_DECODE                            124
+#  define CT_F_CT_POLICY_EVAL_CTX_NEW                      133
+#  define CT_F_CT_V1_LOG_ID_FROM_PKEY                      125
+#  define CT_F_I2O_SCT                                     107
+#  define CT_F_I2O_SCT_LIST                                108
+#  define CT_F_I2O_SCT_SIGNATURE                           109
+#  define CT_F_O2I_SCT                                     110
+#  define CT_F_O2I_SCT_LIST                                111
+#  define CT_F_O2I_SCT_SIGNATURE                           112
+#  define CT_F_SCT_CTX_NEW                                 126
+#  define CT_F_SCT_CTX_VERIFY                              128
+#  define CT_F_SCT_NEW                                     100
+#  define CT_F_SCT_NEW_FROM_BASE64                         127
+#  define CT_F_SCT_SET0_LOG_ID                             101
+#  define CT_F_SCT_SET1_EXTENSIONS                         114
+#  define CT_F_SCT_SET1_LOG_ID                             115
+#  define CT_F_SCT_SET1_SIGNATURE                          116
+#  define CT_F_SCT_SET_LOG_ENTRY_TYPE                      102
+#  define CT_F_SCT_SET_SIGNATURE_NID                       103
+#  define CT_F_SCT_SET_VERSION                             104
+
+/*
+ * CT reason codes.
+ */
+#  define CT_R_BASE64_DECODE_ERROR                         108
+#  define CT_R_INVALID_LOG_ID_LENGTH                       100
+#  define CT_R_LOG_CONF_INVALID                            109
+#  define CT_R_LOG_CONF_INVALID_KEY                        110
+#  define CT_R_LOG_CONF_MISSING_DESCRIPTION                111
+#  define CT_R_LOG_CONF_MISSING_KEY                        112
+#  define CT_R_LOG_KEY_INVALID                             113
+#  define CT_R_SCT_FUTURE_TIMESTAMP                        116
+#  define CT_R_SCT_INVALID                                 104
+#  define CT_R_SCT_INVALID_SIGNATURE                       107
+#  define CT_R_SCT_LIST_INVALID                            105
+#  define CT_R_SCT_LOG_ID_MISMATCH                         114
+#  define CT_R_SCT_NOT_SET                                 106
+#  define CT_R_SCT_UNSUPPORTED_VERSION                     115
+#  define CT_R_UNRECOGNIZED_SIGNATURE_NID                  101
+#  define CT_R_UNSUPPORTED_ENTRY_TYPE                      102
+#  define CT_R_UNSUPPORTED_VERSION                         103
+
+# endif
+#endif

+ 174 - 0
rambus_sec_lib/include/openssl/des.h

@@ -0,0 +1,174 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_DES_H
+# define HEADER_DES_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_DES
+# ifdef  __cplusplus
+extern "C" {
+# endif
+# include <openssl/e_os2.h>
+
+typedef unsigned int DES_LONG;
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/*
+ * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and
+ * const_DES_cblock * are incompatible pointer types.
+ */
+
+typedef struct DES_ks {
+    union {
+        DES_cblock cblock;
+        /*
+         * make sure things are correct size on machines with 8 byte longs
+         */
+        DES_LONG deslong[2];
+    } ks[16];
+} DES_key_schedule;
+
+# define DES_KEY_SZ      (sizeof(DES_cblock))
+# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+# define DES_ENCRYPT     1
+# define DES_DECRYPT     0
+
+# define DES_CBC_MODE    0
+# define DES_PCBC_MODE   1
+
+# define DES_ecb2_encrypt(i,o,k1,k2,e) \
+        DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+        DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+        DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+        DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */
+# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+
+const char *DES_options(void);
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+                      DES_key_schedule *ks1, DES_key_schedule *ks2,
+                      DES_key_schedule *ks3, int enc);
+DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
+                       long length, DES_key_schedule *schedule,
+                       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, const_DES_cblock *inw,
+                      const_DES_cblock *outw, int enc);
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks, int enc);
+
+/*
+ * This is the DES encryption function that gets called by just about every
+ * other DES routine in the library.  You should not use this function except
+ * to implement 'modes' of DES.  I say this because the functions that call
+ * this routine do the conversion from 'char *' to long, and this needs to be
+ * done to make sure 'non-aligned' memory access do not occur.  The
+ * characters are loaded 'little endian'. Data is a pointer to 2 unsigned
+ * long's and ks is the DES_key_schedule to use.  enc, is non zero specifies
+ * encryption, zero if decryption.
+ */
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+/*
+ * This functions is the same as DES_encrypt1() except that the DES initial
+ * permutation (IP) and final permutation (FP) have been left out.  As for
+ * DES_encrypt1(), you should not use this function. It is used by the
+ * routines in the library that implement triple DES. IP() DES_encrypt2()
+ * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1()
+ * DES_encrypt1() DES_encrypt1() except faster :-).
+ */
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                          long length,
+                          DES_key_schedule *ks1, DES_key_schedule *ks2,
+                          DES_key_schedule *ks3, DES_cblock *ivec, int enc);
+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                            long length, DES_key_schedule *ks1,
+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
+                            DES_cblock *ivec, int *num, int enc);
+void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
+                          int numbits, long length, DES_key_schedule *ks1,
+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
+                          DES_cblock *ivec, int enc);
+void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                            long length, DES_key_schedule *ks1,
+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
+                            DES_cblock *ivec, int *num);
+char *DES_fcrypt(const char *buf, const char *salt, char *ret);
+char *DES_crypt(const char *buf, const char *salt);
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+                        long length, int out_count, DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/*
+ * DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise.
+ */
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
+void DES_string_to_key(const char *str, DES_cblock *key);
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num, int enc);
+void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num);
+
+# define DES_fixup_key_parity DES_set_odd_parity
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif

+ 340 - 0
rambus_sec_lib/include/openssl/dh.h

@@ -0,0 +1,340 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_DH_H
+# define HEADER_DH_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_DH
+# include <openssl/e_os2.h>
+# include <openssl/bio.h>
+# include <openssl/asn1.h>
+# include <openssl/ossl_typ.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+# include <openssl/dherr.h>
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# ifndef OPENSSL_DH_MAX_MODULUS_BITS
+#  define OPENSSL_DH_MAX_MODULUS_BITS    10000
+# endif
+
+# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
+
+# define DH_FLAG_CACHE_MONT_P     0x01
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * Does nothing. Previously this switched off constant time behaviour.
+ */
+#  define DH_FLAG_NO_EXP_CONSTTIME 0x00
+# endif
+
+/*
+ * If this flag is set the DH method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define DH_FLAG_FIPS_METHOD                     0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DH_FLAG_NON_FIPS_ALLOW                  0x0400
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+DECLARE_ASN1_ITEM(DHparams)
+
+# define DH_GENERATOR_2          2
+/* #define DH_GENERATOR_3       3 */
+# define DH_GENERATOR_5          5
+
+/* DH_check error codes */
+# define DH_CHECK_P_NOT_PRIME            0x01
+# define DH_CHECK_P_NOT_SAFE_PRIME       0x02
+# define DH_UNABLE_TO_CHECK_GENERATOR    0x04
+# define DH_NOT_SUITABLE_GENERATOR       0x08
+# define DH_CHECK_Q_NOT_PRIME            0x10
+# define DH_CHECK_INVALID_Q_VALUE        0x20
+# define DH_CHECK_INVALID_J_VALUE        0x40
+
+/* DH_check_pub_key error codes */
+# define DH_CHECK_PUBKEY_TOO_SMALL       0x01
+# define DH_CHECK_PUBKEY_TOO_LARGE       0x02
+# define DH_CHECK_PUBKEY_INVALID         0x04
+
+/*
+ * primes p where (p-1)/2 is prime too are called "safe"; we define this for
+ * backward compatibility:
+ */
+# define DH_CHECK_P_NOT_STRONG_PRIME     DH_CHECK_P_NOT_SAFE_PRIME
+
+# define d2i_DHparams_fp(fp,x) \
+    (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+                      (char *(*)())d2i_DHparams, \
+                      (fp), \
+                      (unsigned char **)(x))
+# define i2d_DHparams_fp(fp,x) \
+    ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x))
+# define d2i_DHparams_bio(bp,x) \
+    ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x)
+# define i2d_DHparams_bio(bp,x) \
+    ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+# define d2i_DHxparams_fp(fp,x) \
+    (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+                      (char *(*)())d2i_DHxparams, \
+                      (fp), \
+                      (unsigned char **)(x))
+# define i2d_DHxparams_fp(fp,x) \
+    ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x))
+# define d2i_DHxparams_bio(bp,x) \
+    ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x)
+# define i2d_DHxparams_bio(bp,x) \
+    ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)
+
+DH *DHparams_dup(DH *);
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *DH_new(void);
+void DH_free(DH *dh);
+int DH_up_ref(DH *dh);
+int DH_bits(const DH *dh);
+int DH_size(const DH *dh);
+int DH_security_bits(const DH *dh);
+#define DH_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, l, p, newf, dupf, freef)
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator,
+                                              void (*callback) (int, int,
+                                                                void *),
+                                              void *cb_arg))
+
+/* New version */
+int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
+                              BN_GENCB *cb);
+
+int DH_check_params_ex(const DH *dh);
+int DH_check_ex(const DH *dh);
+int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key);
+int DH_check_params(const DH *dh, int *ret);
+int DH_check(const DH *dh, int *codes);
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
+int DH_generate_key(DH *dh);
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHparams(const DH *a, unsigned char **pp);
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHxparams(const DH *a, unsigned char **pp);
+# ifndef OPENSSL_NO_STDIO
+int DHparams_print_fp(FILE *fp, const DH *x);
+# endif
+int DHparams_print(BIO *bp, const DH *x);
+
+/* RFC 5114 parameters */
+DH *DH_get_1024_160(void);
+DH *DH_get_2048_224(void);
+DH *DH_get_2048_256(void);
+
+/* Named parameters, currently RFC7919 */
+DH *DH_new_by_nid(int nid);
+int DH_get_nid(const DH *dh);
+
+# ifndef OPENSSL_NO_CMS
+/* RFC2631 KDF */
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md);
+# endif
+
+void DH_get0_pqg(const DH *dh,
+                 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DH_get0_key(const DH *dh,
+                 const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+const BIGNUM *DH_get0_p(const DH *dh);
+const BIGNUM *DH_get0_q(const DH *dh);
+const BIGNUM *DH_get0_g(const DH *dh);
+const BIGNUM *DH_get0_priv_key(const DH *dh);
+const BIGNUM *DH_get0_pub_key(const DH *dh);
+void DH_clear_flags(DH *dh, int flags);
+int DH_test_flags(const DH *dh, int flags);
+void DH_set_flags(DH *dh, int flags);
+ENGINE *DH_get0_engine(DH *d);
+long DH_get_length(const DH *dh);
+int DH_set_length(DH *dh, long length);
+
+DH_METHOD *DH_meth_new(const char *name, int flags);
+void DH_meth_free(DH_METHOD *dhm);
+DH_METHOD *DH_meth_dup(const DH_METHOD *dhm);
+const char *DH_meth_get0_name(const DH_METHOD *dhm);
+int DH_meth_set1_name(DH_METHOD *dhm, const char *name);
+int DH_meth_get_flags(const DH_METHOD *dhm);
+int DH_meth_set_flags(DH_METHOD *dhm, int flags);
+void *DH_meth_get0_app_data(const DH_METHOD *dhm);
+int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data);
+int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *);
+int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *));
+int (*DH_meth_get_compute_key(const DH_METHOD *dhm))
+        (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_meth_set_compute_key(DH_METHOD *dhm,
+        int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh));
+int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm))
+    (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+     BN_CTX *, BN_MONT_CTX *);
+int DH_meth_set_bn_mod_exp(DH_METHOD *dhm,
+    int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *));
+int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *);
+int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *));
+int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *);
+int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *));
+int (*DH_meth_get_generate_params(const DH_METHOD *dhm))
+        (DH *, int, int, BN_GENCB *);
+int DH_meth_set_generate_params(DH_METHOD *dhm,
+        int (*generate_params) (DH *, int, int, BN_GENCB *));
+
+
+# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_nid(ctx, nid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, \
+                        EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, \
+                        EVP_PKEY_CTRL_DH_NID, nid, NULL)
+
+# define EVP_PKEY_CTX_set_dh_pad(ctx, pad) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, \
+                          EVP_PKEY_CTRL_DH_PAD, pad, NULL)
+
+# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid))
+
+# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(poid))
+
+# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md))
+
+# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd))
+
+# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)(plen))
+
+# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)(p))
+
+# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(p))
+
+# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN     (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR     (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DH_RFC5114                (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN  (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE          (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_DH_KDF_TYPE               (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_DH_KDF_MD                 (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_DH_KDF_MD             (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_DH_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN         (EVP_PKEY_ALG_CTRL + 10)
+# define EVP_PKEY_CTRL_DH_KDF_UKM                (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_DH_KDF_UKM            (EVP_PKEY_ALG_CTRL + 12)
+# define EVP_PKEY_CTRL_DH_KDF_OID                (EVP_PKEY_ALG_CTRL + 13)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OID            (EVP_PKEY_ALG_CTRL + 14)
+# define EVP_PKEY_CTRL_DH_NID                    (EVP_PKEY_ALG_CTRL + 15)
+# define EVP_PKEY_CTRL_DH_PAD                    (EVP_PKEY_ALG_CTRL + 16)
+
+/* KDF types */
+# define EVP_PKEY_DH_KDF_NONE                            1
+# ifndef OPENSSL_NO_CMS
+# define EVP_PKEY_DH_KDF_X9_42                           2
+# endif
+
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif

Some files were not shown because too many files changed in this diff