summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2016-12-06 10:42:23 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-01-30 11:18:51 -0500
commit6b650f5428297e8dde075d25e7862a20c8d47f04 (patch)
treeb268ac9fb258732a7aea73179c2f09992b76cc36
parentaff3f67b49b87d5e2755b364ecb512641bbb4540 (diff)
downloadtalos-hostboot-6b650f5428297e8dde075d25e7862a20c8d47f04.tar.gz
talos-hostboot-6b650f5428297e8dde075d25e7862a20c8d47f04.zip
Compile ROM code within Hostboot
Additionally added version id to resolve story 135747 RTC: 143902 Change-Id: I67ad4b28b76464aaa58ec2c344cd1f9ceef9ff73 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33608 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/bootloader/bl_start.S4
-rw-r--r--src/build/linker/linker.C63
-rw-r--r--src/build/mkrules/images.rules.mk3
-rwxr-xr-xsrc/build/tools/addimgid8
-rw-r--r--src/include/securerom/ROM.H62
-rw-r--r--src/include/securerom/ecverify.H11
-rw-r--r--src/include/securerom/hw_utils.H387
-rw-r--r--src/include/securerom/sha512.H27
-rw-r--r--src/include/securerom/status_codes.H19
-rw-r--r--src/lib/makefile3
-rw-r--r--src/lib/string.C97
-rw-r--r--src/lib/string_utils.C119
-rw-r--r--src/makefile17
-rw-r--r--src/securerom.ld104
-rw-r--r--src/securerom/ROM.C665
-rw-r--r--src/securerom/branchtable.S88
-rw-r--r--src/securerom/ecverify.C2009
-rw-r--r--src/securerom/hw_utils.C252
-rw-r--r--src/securerom/inttypes.H1
-rw-r--r--src/securerom/makefile231
-rw-r--r--src/securerom/sha512.C681
21 files changed, 2092 insertions, 2759 deletions
diff --git a/src/bootloader/bl_start.S b/src/bootloader/bl_start.S
index a60c85a7c..99843a1eb 100644
--- a/src/bootloader/bl_start.S
+++ b/src/bootloader/bl_start.S
@@ -419,6 +419,10 @@ bootloader_trace:
bootloader_hbbSection:
.space 32
+.global hbi_ImageId
+hbi_ImageId:
+ .space 128
+
.balign 16
.global bootloader_end_eyecatcher
bootloader_end_eyecatcher:
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C
index fb154d989..d00b56a98 100644
--- a/src/build/linker/linker.C
+++ b/src/build/linker/linker.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -288,6 +288,7 @@ map<string,size_t> weak_symbols;
set<string> all_symbols;
set<string> weak_symbols_to_check;
bool includes_extended_image = false;
+bool relocation = true;
size_t next_tls_id = 0;
@@ -304,7 +305,7 @@ int main(int argc, char** argv)
if (argc <= 2)
{
cout << argv[0] << " <output> <kernel> <modules>"
- " [--extended=<page_addr> <output> <modules>]" << endl;
+ " [--no-relocation] [--extended=<page_addr> <output> <modules>]" << endl;
return -1;
}
@@ -317,7 +318,11 @@ int main(int argc, char** argv)
for (int files = 1; files < argc; files++)
{
string fname(argv[files]);
- if(isOutput)
+ if (0 == fname.compare(0,15,"--no-relocation"))
+ {
+ relocation = false;
+ }
+ else if(isOutput)
{
isOutput = false;
output = fopen(fname.c_str(), "w+");
@@ -444,35 +449,39 @@ int main(int argc, char** argv)
// Only appies to base binary file
//
- cout << "Updating last address..." << std::hex;
- const Symbol& last_address_symbol =
- objects[0].symbols[VFS_TOSTRING(VFS_LAST_ADDRESS)];
- uint64_t last_address_entry_address =
- last_address_symbol.address + last_address_symbol.base +
- objects[0].offset;
-
- fseek(objects[0].iv_output, last_address_entry_address, SEEK_SET);
-
- char last_addr_data[sizeof(uint64_t)];
- bfd_putb64(last_address, last_addr_data);
- fwrite(last_addr_data, sizeof(uint64_t), 1, objects[0].iv_output);
+ // Ignore if relocation not needed for image.
+ if (relocation)
+ {
+ cout << "Updating last address..." << std::hex;
+ const Symbol& last_address_symbol =
+ objects[0].symbols[VFS_TOSTRING(VFS_LAST_ADDRESS)];
+ uint64_t last_address_entry_address =
+ last_address_symbol.address + last_address_symbol.base +
+ objects[0].offset;
- cout << last_address << " to " << last_address_entry_address << endl;
+ fseek(objects[0].iv_output, last_address_entry_address, SEEK_SET);
- // Output relocation data for single file images. (non-extended)
- if (!includes_extended_image)
- {
- fseek(objects[0].iv_output, 0, SEEK_END);
- char temp64[sizeof(uint64_t)];
+ char last_addr_data[sizeof(uint64_t)];
+ bfd_putb64(last_address, last_addr_data);
+ fwrite(last_addr_data, sizeof(uint64_t), 1, objects[0].iv_output);
- uint64_t count = all_relocations.size();
- bfd_putb64(count, temp64);
- fwrite(temp64, sizeof(uint64_t), 1, objects[0].iv_output);
+ cout << last_address << " to " << last_address_entry_address << endl;
- for (int i = 0; i < all_relocations.size(); i++)
+ // Output relocation data for single file images. (non-extended)
+ if (!includes_extended_image)
{
- bfd_putb64(all_relocations[i], temp64);
+ fseek(objects[0].iv_output, 0, SEEK_END);
+ char temp64[sizeof(uint64_t)];
+
+ uint64_t count = all_relocations.size();
+ bfd_putb64(count, temp64);
fwrite(temp64, sizeof(uint64_t), 1, objects[0].iv_output);
+
+ for (int i = 0; i < all_relocations.size(); i++)
+ {
+ bfd_putb64(all_relocations[i], temp64);
+ fwrite(temp64, sizeof(uint64_t), 1, objects[0].iv_output);
+ }
}
}
}
@@ -571,6 +580,8 @@ bool Object::write_object()
if(isELF())
{
+ // @TODO RTC: 166850 skip text, rodata, data if .size() is 0. It appears
+ // fseek messes up the offset, if there is 0 size.
// Output TEXT section.
fseek(iv_output, text.vma_offset, SEEK_CUR);
if (text.size != fwrite(text.data, 1, text.size, iv_output))
diff --git a/src/build/mkrules/images.rules.mk b/src/build/mkrules/images.rules.mk
index 92722dba2..2a611b030 100644
--- a/src/build/mkrules/images.rules.mk
+++ b/src/build/mkrules/images.rules.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2016
+# Contributors Listed Below - COPYRIGHT 2013,2017
# [+] International Business Machines Corp.
#
#
@@ -58,6 +58,7 @@ $(IMGDIR)/%.bin: $(IMGDIR)/%.elf \
$(addprefix $(IMGDIR)/lib, \
$(addsuffix .so, $($*_EXTENDED_MODULES))) \
) \
+ $(if $($*_NO_RELOCATION), --no-relocation) \
$(addprefix $(IMGDIR)/, $($*_DATA_MODULES)) \
| bzip2 -zc > $(IMGDIR)/.$*.lnkout.bz2'
$(C1)$(ROOTPATH)/src/build/tools/addimgid $@ $<
diff --git a/src/build/tools/addimgid b/src/build/tools/addimgid
index abd8e7de6..255cc431b 100755
--- a/src/build/tools/addimgid
+++ b/src/build/tools/addimgid
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2016
+# Contributors Listed Below - COPYRIGHT 2011,2017
# [+] International Business Machines Corp.
#
#
@@ -31,12 +31,6 @@ my $imageIdSym = "hbi_ImageId";
my $img = shift;
my $src = shift;
-if(($img =~ /.*bootloader.*/) || ($src =~ /.*bootloader.*/))
-{
- # @TODO RTC:135747 Add version/id tag to binary
- exit $?
-}
-
my $imgBase = $img;
$imgBase =~ s/.*\///;
diff --git a/src/include/securerom/ROM.H b/src/include/securerom/ROM.H
index 315a436d0..808a87468 100644
--- a/src/include/securerom/ROM.H
+++ b/src/include/securerom/ROM.H
@@ -22,41 +22,36 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/****************************************************************************
- *
- ****************************************************************************/
+
#ifndef ROM_H
#define ROM_H
-/****************************************************************************/
-#ifndef PHYPLIBFUNCTIONS
-#include <hw_utils.h>
-#endif
-#include <sha512.h>
-#include <ecverify.h>
+#include <securerom/hw_utils.H>
+#include <securerom/sha512.H>
+#include <securerom/ecverify.H>
-/****************************************************************************/
#define CONTAINER_VERSION 1
#define HEADER_VERSION 1
#define HASH_ALG_SHA512 1
#define SIG_ALG_ECDSA521 1
-#define HBI_BASE_SIGNING_KEY 0x80000000
-
#define ROM_MAGIC_NUMBER 0x17082011
-typedef struct {
+typedef struct
+{
uint16_t version; // (1: see versions above)
uint8_t hash_alg; // (1: SHA-512)
uint8_t sig_alg; // (1: SHA-512/ECDSA-521)
}__attribute__((packed)) ROM_version_raw;
-typedef struct {
+typedef struct
+{
uint32_t magic_number; // (17082011)
uint16_t version; // (1: see versions above)
uint64_t container_size; // filled by caller
uint64_t target_hrmor; // filled by caller
- uint64_t stack_pointer; // filled by caller //bottom of stack -> 128k added by rom code to get real stack pointer
+ //bottom of stack -> 128k added by rom code to get real stack pointer
+ uint64_t stack_pointer; // filled by caller
ecc_key_t hw_pkey_a;
ecc_key_t hw_pkey_b;
ecc_key_t hw_pkey_c;
@@ -65,7 +60,8 @@ typedef struct {
// followed by optional unprotected payload data
}__attribute__((packed)) ROM_container_raw;
-typedef struct {
+typedef struct
+{
ROM_version_raw ver_alg;
uint64_t code_start_offset;
uint64_t reserved;
@@ -74,13 +70,16 @@ typedef struct {
uint64_t payload_size;
sha2_hash_t payload_hash;
uint8_t ecid_count;
- uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
+ // optional ecid place holder ecid_count * ecid_size(128 bits)
+ uint8_t ecid[ECID_SIZE];
// followed by prefix data (sig,keys) key raw
}__attribute__((packed)) ROM_prefix_header_raw;
-#define PREFIX_HEADER_SIZE(_p) (sizeof(ROM_prefix_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
+#define PREFIX_HEADER_SIZE(_p) (sizeof(ROM_prefix_header_raw) \
+ +((_p->ecid_count-1)*ECID_SIZE))
-typedef struct {
+typedef struct
+{
ecc_signature_t hw_sig_a;
ecc_signature_t hw_sig_b;
ecc_signature_t hw_sig_c;
@@ -89,7 +88,8 @@ typedef struct {
ecc_key_t sw_pkey_r;
}__attribute__((packed)) ROM_prefix_data_raw;
-typedef struct {
+typedef struct
+{
ROM_version_raw ver_alg;
uint64_t code_start_offset;
uint64_t reserved;
@@ -98,13 +98,16 @@ typedef struct {
uint64_t payload_size;
sha2_hash_t payload_hash;
uint8_t ecid_count;
- uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
+ // optional ecid place holder ecid_count * ecid_size(128 bits)
+ uint8_t ecid[ECID_SIZE];
// followed by sw sig raw
}__attribute__((packed)) ROM_sw_header_raw;
-#define SW_HEADER_SIZE(_p) (sizeof(ROM_sw_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
+#define SW_HEADER_SIZE(_p) (sizeof(ROM_sw_header_raw) \
+ +((_p->ecid_count-1)*ECID_SIZE))
-typedef struct {
+typedef struct
+{
ecc_signature_t sw_sig_p;
ecc_signature_t sw_sig_q;
ecc_signature_t sw_sig_r;
@@ -113,21 +116,18 @@ typedef struct {
// followed by unprotected sw payload_text
}__attribute__((packed)) ROM_sw_sig_raw;
-/****************************************************************************/
-typedef enum { ROM_DONE, ROM_FAILED, PHYP_PARTIAL } ROM_response;
+typedef enum { ROM_DONE, ROM_FAILED } ROM_response;
-#ifndef PHYPLIBFUNCTIONS
-typedef struct {
+typedef struct
+{
sha2_hash_t hw_key_hash;
uint8_t my_ecid[ECID_SIZE];
uint64_t entry_point;
uint64_t log;
}__attribute__((packed)) ROM_hw_params;
-//extern void ROM_instruction_start (void);
extern void ROM_sreset (void);
-extern ROM_response ROM_verify (ROM_container_raw* container,
- ROM_hw_params* params);
-#endif
+extern "C" ROM_response ROM_verify (ROM_container_raw* container,
+ ROM_hw_params* params);
#endif
diff --git a/src/include/securerom/ecverify.H b/src/include/securerom/ecverify.H
index b7c707803..6c6bfe07c 100644
--- a/src/include/securerom/ecverify.H
+++ b/src/include/securerom/ecverify.H
@@ -22,19 +22,11 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/*----------------------------------------------------------------------
- * (C) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 2010
- * ALL RIGHTS RESERVED
- * IBM Research, Zurich and IBM Crypto Competency Center, Copenhagen
- *----------------------------------------------------------------------
- * Author: Tamas Visegrady (tvi@zurich.ibm.com)
- *----------------------------------------------------------------------*/
#if !defined(__ECVERIFY_H__)
#define __ECVERIFY_H__
-/** ECDSA verification on fixed curve
- */
+// ECDSA verification on fixed curve
#define EC_HASHBYTES 64 /* SHA-256 */
#define EC_COORDBYTES 66 /* P-521 */
@@ -46,6 +38,7 @@ typedef uint8_t ecc_signature_t[2*EC_COORDBYTES];
* zero if parameters are valid but signature verification fails
* negative if parameters (such as point) are invalid
*/
+extern "C"
int ec_verify (const uint8_t *publicpt, /* 2*EC_COORDBYTES */
const uint8_t *hash, /* EC_HASHBYTES */
const uint8_t *signature) ; /* 2*EC_COORDBYTES */
diff --git a/src/include/securerom/hw_utils.H b/src/include/securerom/hw_utils.H
index 324cdfc25..014d82d20 100644
--- a/src/include/securerom/hw_utils.H
+++ b/src/include/securerom/hw_utils.H
@@ -22,22 +22,20 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/****************************************************************************
- *
- ****************************************************************************/
+
#ifndef HW_UTILS_H
#define HW_UTILS_H
#include <stdint.h>
-#include "sha512.h"
-#include "status_codes.h"
+#include <securerom/sha512.H>
+#include <securerom/status_codes.H>
#define ECID_SIZE 16
#define CACHE_LINE 128
#define XSCOM_MASK 0x0003fe0000000000ull // bit 14:22 implemented
#define HRMOR_MASK 0x0003fffffe000000ull // 32MB aligned
-#define STACK_MASK 0x0003fffffffff000ull // 4KB page aligned //WEH bug fix
+#define STACK_MASK 0x0003fffffffff000ull // 4KB page aligned
#define ENTRY_MASK 0x7ffffffffffffffCull // 4Byte page aligned
#define HRMOR_IGNORE 0x8000000000000000ull
@@ -66,22 +64,24 @@ extern int GOOD;
#define CHECK_STOP(_m) Check_Stop(_m)
#define ERROR_STOP(_c,_m) Error_Stop(CONTEXT|(_c), _m)
-typedef struct {
- uint64_t GPR[32];
- uint64_t SCRATCH0;
- uint64_t SCRATCH1;
- uint64_t SCRATCH2;
- uint64_t SCRATCH3;
- uint64_t HRMOR;
- struct {
- uint64_t value;
- uint64_t mask;
- } FSP_BAR;
- uint8_t ECID[ECID_SIZE];
- sha2_hash_t PIBMEM_HW_KEY_HASH;
- uint8_t* data; // 64M+4K malloc/mmap
- uint8_t* memory; // 64M (4K aligned)
- int mfd;
+typedef struct
+{
+ uint64_t GPR[32];
+ uint64_t SCRATCH0;
+ uint64_t SCRATCH1;
+ uint64_t SCRATCH2;
+ uint64_t SCRATCH3;
+ uint64_t HRMOR;
+ struct
+ {
+ uint64_t value;
+ uint64_t mask;
+ } FSP_BAR;
+ uint8_t ECID[ECID_SIZE];
+ sha2_hash_t PIBMEM_HW_KEY_HASH;
+ uint8_t* data; // 64M+4K malloc/mmap
+ uint8_t* memory; // 64M (4K aligned)
+ int mfd;
} hw_settings;
extern hw_settings HW;
@@ -107,49 +107,55 @@ extern void assem_ISYNC (void);
extern void mtspr_HRMOR (uint64_t addr);
//extern uint64_t mfspr_HRMOR (void);
-static inline uint64_t mfspr_SCRATCH0(void) {
- return HW.SCRATCH0;
+static inline uint64_t mfspr_SCRATCH0(void)
+{
+ return HW.SCRATCH0;
}
-static inline void mtspr_SCRATCH0(uint64_t val) {
- HW.SCRATCH0 = val;
+static inline void mtspr_SCRATCH0(uint64_t val)
+{
+ HW.SCRATCH0 = val;
}
-static inline uint64_t mfspr_SCRATCH1(void) {
- return HW.SCRATCH1;
+static inline uint64_t mfspr_SCRATCH1(void)
+{
+ return HW.SCRATCH1;
}
-static inline void mtspr_SCRATCH1(uint64_t val) {
- HW.SCRATCH1 = val;
+static inline void mtspr_SCRATCH1(uint64_t val)
+{
+ HW.SCRATCH1 = val;
}
-static inline void mtspr_SCRATCH2(uint64_t val) {
- HW.SCRATCH2 = val;
+static inline void mtspr_SCRATCH2(uint64_t val)
+{
+ HW.SCRATCH2 = val;
}
-static inline uint64_t mfspr_SCRATCH2(void) {
- return HW.SCRATCH2;
+static inline uint64_t mfspr_SCRATCH2(void)
+{
+ return HW.SCRATCH2;
}
-static inline void mtspr_SCRATCH3(uint64_t val) {
- HW.SCRATCH3 = val;
+static inline void mtspr_SCRATCH3(uint64_t val)
+{
+ HW.SCRATCH3 = val;
}
-static inline uint64_t mfspr_SCRATCH3(void) {
- return HW.SCRATCH3;
+static inline uint64_t mfspr_SCRATCH3(void)
+{
+ return HW.SCRATCH3;
}
extern uint64_t getscom_FSP_BAR_value (uint64_t base);
extern uint64_t getscom_FSP_BAR_mask (uint64_t base);
-extern void getscom_HW_ECID (uint64_t base, uint8_t* buf);
-extern void getscom_PIBMEM_HW_Key_Hash (uint64_t base, uint8_t* buf);
+extern void getscom_HW_ECID (uint64_t base, uint8_t* buf);
extern uint64_t physical_addr (uint64_t addr);
extern uint8_t* Convert_Mem_Addr (uint64_t);
extern uint64_t Convert_Mem_Offset (uint8_t*);
-/****************************************************************************/
extern uint16_t GET16 (uint16_t data);
extern uint32_t GET32 (uint32_t data);
extern uint64_t GET64 (uint64_t data);
@@ -191,230 +197,167 @@ extern uint64_t GET64 (uint64_t data);
#define PSIHB_NOTRUST_BAR1 0x02013f41
#define PSIHB_NOTRUST_BAR1MASK 0x02013f43
-/****************************************************************************/
-static inline void assem_DCBI(uint64_t addr) {
- asm volatile(" dcbi 0,%0 " : : "r" (addr) : "memory");
+static inline void assem_DCBI(uint64_t addr)
+{
+ asm volatile(" dcbi 0,%0 " : : "r" (addr) : "memory");
}
-/****************************************************************************/
-static inline void assem_DCBZ(uint64_t addr) {
- asm volatile(" dcbz 0,%0 " : : "r" (addr) : "memory");
+static inline void assem_DCBZ(uint64_t addr)
+{
+ asm volatile(" dcbz 0,%0 " : : "r" (addr) : "memory");
}
-/****************************************************************************/
-static inline void assem_ICBI(uint64_t* addr) {
- asm volatile(" icbi 0,%0 " : : "r" (addr) : "memory");
+static inline void assem_ICBI(uint64_t* addr)
+{
+ asm volatile(" icbi 0,%0 " : : "r" (addr) : "memory");
}
-/****************************************************************************/
-static inline void assem_SYNC(void) {
- asm volatile("sync 0":::"memory");
+static inline void assem_SYNC(void)
+{
+ asm volatile("sync 0":::"memory");
}
-/****************************************************************************/
-static inline void assem_ISYNC(void) {
- asm volatile("isync":::"memory");
+static inline void assem_ISYNC(void)
+{
+ asm volatile("isync":::"memory");
}
-/****************************************************************************/
-static inline uint64_t mfspr(int reg) {
- unsigned long val;
- asm volatile("mfspr %0, %1" : "=r" (val) : "i" (reg));
- return val;
+static inline uint64_t mfspr(int reg)
+{
+ unsigned long val;
+ asm volatile("mfspr %0, %1" : "=r" (val) : "i" (reg));
+ return val;
}
-static inline void mtspr(int reg, uint64_t val) {
- asm volatile("mtspr %0, %1" : : "i" (reg), "r" (val));
+static inline void mtspr(int reg, uint64_t val)
+{
+ asm volatile("mtspr %0, %1" : : "i" (reg), "r" (val));
}
-/****************************************************************************/
-//
-//static inline uint64_t mfspr_HRMOR(void) {
-// unsigned long val;
-// asm volatile("mfspr %0, %1" : "=r" (val) : "i" (HRMOR));
-// return val;
-//}
-
-static inline void mtspr_HRMOR(uint64_t addr) {
- asm volatile("mtspr %0, %1" : : "i" (HRMOR), "r" (addr & HRMOR_MASK));
+static inline void mtspr_HRMOR(uint64_t addr)
+{
+ asm volatile("mtspr %0, %1" : : "i" (HRMOR), "r" (addr & HRMOR_MASK));
}
-/****************************************************************************/
-#if !(CONFIG_MAMBO && CONFIG_MAMBO_WITHOUT_SCRATCH)
-
-static inline uint64_t mfspr_SCRATCH0(void) {
- mtspr(SPRC,SPRC_SCRATCH0);
- return mfspr(SPRD);
+static inline uint64_t mfspr_SCRATCH0(void)
+{
+ mtspr(SPRC,SPRC_SCRATCH0);
+ return mfspr(SPRD);
}
-static inline void mtspr_SCRATCH0(uint64_t val) {
- mtspr(SPRC,SPRC_SCRATCH0);
- mtspr(SPRD,val);
+static inline void mtspr_SCRATCH0(uint64_t val)
+{
+ mtspr(SPRC,SPRC_SCRATCH0);
+ mtspr(SPRD,val);
}
-static inline uint64_t mfspr_SCRATCH1(void) {
- mtspr(SPRC,SPRC_SCRATCH1);
- return mfspr(SPRD);
+static inline uint64_t mfspr_SCRATCH1(void)
+{
+ mtspr(SPRC,SPRC_SCRATCH1);
+ return mfspr(SPRD);
}
-static inline void mtspr_SCRATCH1(uint64_t val) {
- mtspr(SPRC,SPRC_SCRATCH1);
- mtspr(SPRD,val);
+static inline void mtspr_SCRATCH1(uint64_t val)
+{
+ mtspr(SPRC,SPRC_SCRATCH1);
+ mtspr(SPRD,val);
}
-static inline void mtspr_SCRATCH2(uint64_t val) {
- mtspr(SPRC,SPRC_SCRATCH2);
- mtspr(SPRD,val);
+static inline void mtspr_SCRATCH2(uint64_t val)
+{
+ mtspr(SPRC,SPRC_SCRATCH2);
+ mtspr(SPRD,val);
}
-static inline void mtspr_SCRATCH3(uint64_t val) {
- mtspr(SPRC,SPRC_SCRATCH3);
- mtspr(SPRD,val);
+static inline void mtspr_SCRATCH3(uint64_t val)
+{
+ mtspr(SPRC,SPRC_SCRATCH3);
+ mtspr(SPRD,val);
}
-#else
-
- #define mfspr_SCRATCH0() ci_read( 0x80C0FFEE00000000ull)
- #define mtspr_SCRATCH0(value) ci_write(0x80C0FFEE00000000ull,(value))
- #define mfspr_SCRATCH1() ci_read( 0x80C0FFEE00000008ull)
- #define mtspr_SCRATCH1(value) ci_write(0x80C0FFEE00000008ull,(value))
- #define mfspr_SCRATCH2() ci_read( 0x80C0FFEE00000010ull)
- #define mtspr_SCRATCH2(value) ci_write(0x80C0FFEE00000010ull,(value))
- #define mfspr_SCRATCH3() ci_read( 0x80C0FFEE00000018ull)
- #define mtspr_SCRATCH3(value) ci_write(0x80C0FFEE00000018ull,(value))
-
-#endif
-/****************************************************************************/
-
+extern "C"
void __attribute__((noreturn)) Check_Stop(void);
-/****************************************************************************/
-
#define LOG(_c) mtspr_SCRATCH2(CONTEXT|(_c))
-#define ERROR_STOP(_c,_m) { mtspr_SCRATCH3(ERROR_EVENT|CONTEXT|(_c)); asm volatile("b .Check_Stop"); }
-
+#define ERROR_STOP(_c,_m) { mtspr_SCRATCH3(ERROR_EVENT|CONTEXT|(_c)); \
+ asm volatile("b .Check_Stop"); }
-/****************************************************************************/
-/* Bit 56, 61, 62, 63 is not used in XSCOM addresss and must be 0
- */
-#define PCB2PBUS(scom_addr) \
- ((((scom_addr) & 0x7FFFFFF0) << 4) | \
- (((scom_addr) & 0x0000000F) << 3))
+/* Bit 56, 61, 62, 63 is not used in XSCOM addresss and must be 0 */
+#define PCB2PBUS(scom_addr) \
+ ((((scom_addr) & 0x7FFFFFF0) << 4) | \
+ (((scom_addr) & 0x0000000F) << 3))
-static inline uint64_t ci_read(const uint64_t reg) {
- unsigned long val;
- asm volatile( "ldcix %0, 0, %1"
- : "=r" (val) // output, %0
- : "r" (reg) // input, %1
+static inline uint64_t ci_read(const uint64_t reg)
+{
+ unsigned long val;
+ asm volatile( "ldcix %0, 0, %1"
+ : "=r" (val) // output, %0
+ : "r" (reg) // input, %1
// no impacts
- );
- //old prism code:
- //asm volatile( "ld %0, 0(%1)\n"
- // "eieio"
- // : "=r" (val) /* output */
- // : "r" (reg) /* input */
- // );
+ );
return val;
}
-
-static inline void ci_write(const uint64_t reg, uint64_t val) {
- asm volatile("stdcix %0, 0, %1"
- : // no outputs
- : "r" (val), "r" (reg) // inputs, %0, %1
- : "memory" // affects memory
- );
- //old prism code:
- //asm volatile("st %0, 0(%1)\n"
- // "eieio"
- // : /* output */
- // : "r" (val) , "r" (reg) /* input */
- // : "memory");
+static inline void ci_write(const uint64_t reg, uint64_t val)
+{
+ asm volatile("stdcix %0, 0, %1"
+ : // no outputs
+ : "r" (val), "r" (reg) // inputs, %0, %1
+ : "memory" // affects memory
+ );
}
-#ifndef CONFIG_MAMBO
-
- #define getscom(a, b) _getscom((a)+PCB2PBUS(b))
- static inline uint64_t _getscom(uint64_t addr) {
- mtspr(HMER,0);
- uint64_t value;
- uint64_t rslt;
- do {
- value = ci_read(addr);
+#define getscom(a, b) _getscom((a)+PCB2PBUS(b))
+static inline uint64_t _getscom(uint64_t addr)
+{
+ mtspr(HMER,0);
+ uint64_t value;
+ uint64_t rslt;
do {
- rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL);
- } while( (rslt & HMER_XSCOM_DONE)==0 );
- } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry
- if(rslt != HMER_XSCOM_DONE){
- ERROR_STOP(XSCOM_ERROR,"XScom read returned unexpected result code");
- }
- return value;
- }
-
- #define putscom(xscom_base, scom_addr, value) _putscom(xscom_base + PCB2PBUS(scom_addr),value)
- static inline void _putscom(uint64_t addr, uint64_t value) {
- mtspr(HMER,0);
- uint64_t rslt = -1;
- do {
- ci_write(addr,value);
- do {
- rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL);
- } while( (rslt & HMER_XSCOM_DONE)==0 );
- } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry
- if(rslt != HMER_XSCOM_DONE){
- ERROR_STOP(XSCOM_ERROR,"XScom write returned unexpected result code");
- }
- }
-
-#else
-
- #define getscom(xscom_base, scom_addr) ci_read(xscom_base+scom_addr*8)
- #define putscom(xscom_base, scom_addr, value) ci_write(xscom_base+scom_addr*8,value)
-
-#endif
-
-
-
-static inline uint64_t popcountll(uint64_t input) {
- unsigned long result;
- asm volatile("popcntd %0, %1" : "=r" (result) : "r" (input));
- return result;
+ value = ci_read(addr);
+ do {
+ rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL);
+ } while( (rslt & HMER_XSCOM_DONE)==0 );
+ } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry
+ if(rslt != HMER_XSCOM_DONE)
+ {
+ ERROR_STOP(XSCOM_ERROR,"XScom read returned unexpected result code");
+ }
+ return value;
}
-/****************************************************************************/
-static inline void getscom_HW_ECID(uint64_t base, uint8_t* buf) {
- uint64_t* buf64 = (uint64_t *) buf;
- unsigned int i;
-// uint64_t sum=0; // detect any change after fuse programming
- for(i=0; i<ECID_SIZE/sizeof(uint64_t);i++) {
- uint64_t val=getscom(base,OTP_ECID+i);
-// sum += popcountll(val);
- buf64[i] = val;
- }
-// const unsigned int count = sizeof(sha2_hash_t)/sizeof(uint64_t);
-// uint64_t lastval=getscom(base,OTP_HW_KEY_HASH+count);
-// if(((lastval & 0x00000000FFFF0000UL)>>16) != (~sum)) {
-// ERROR_STOP(OTP_ECID_INVPOPSUM_CHECK,"Inverted Populationcount of ECID does not match");
-// }
+#define putscom(xscom_base, scom_addr, value) _putscom(xscom_base \
+ + PCB2PBUS(scom_addr),value)
+static inline void _putscom(uint64_t addr, uint64_t value)
+{
+ mtspr(HMER,0);
+ uint64_t rslt = -1;
+ do {
+ ci_write(addr,value);
+ do {
+ rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL);
+ } while( (rslt & HMER_XSCOM_DONE)==0 );
+ } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry
+ if(rslt != HMER_XSCOM_DONE)
+ {
+ ERROR_STOP(XSCOM_ERROR,"XScom write returned unexpected result code");
+ }
}
-/****************************************************************************/
-static inline void getscom_PIBMEM_HW_Key_Hash(uint64_t base, uint8_t* buf) {
-
- uint64_t* buf64 = (uint64_t *) buf;
- unsigned int i;
- const unsigned int count = sizeof(sha2_hash_t)/sizeof(uint64_t);
- uint64_t sum=0; // detect any change after fuse programming
- for(i=0; i<count;i++) {
- uint64_t val=getscom(base,PIBMEM_HW_KEY_HASH+i);
- sum += popcountll(val);
- buf64[i] = val;
- }
- //uint64_t lastval=getscom(base,OTP_HW_KEY_HASH+count);
- //sum += popcountll(lastval & 0xFFFFFFFFFFFF0000UL);
- //if((lastval & 0x000000000000FFFFUL) != (~sum)) {
- // ERROR_STOP(OTP_KEY_INVPOPSUM_CHECK,"Inverted Populationcount of ECID does not match");
- //}
+static inline uint64_t popcountll(uint64_t input)
+{
+ unsigned long result;
+ asm volatile("popcntd %0, %1" : "=r" (result) : "r" (input));
+ return result;
}
-/****************************************************************************/
+static inline void getscom_HW_ECID(uint64_t base, uint8_t* buf)
+{
+ uint64_t* buf64 = (uint64_t *) buf;
+ unsigned int i;
+ for(i=0; i<ECID_SIZE/sizeof(uint64_t);i++)
+ {
+ uint64_t val=getscom(base,OTP_ECID+i);
+ buf64[i] = val;
+ }
+}
#define Convert_Mem_Addr(_addr) ((uint8_t*) (_addr))
#define Convert_Mem_Offset(_addr) ((uint64_t) (_addr))
diff --git a/src/include/securerom/sha512.H b/src/include/securerom/sha512.H
index 4a87aaf4e..ef0fa3160 100644
--- a/src/include/securerom/sha512.H
+++ b/src/include/securerom/sha512.H
@@ -25,27 +25,32 @@
#ifndef SHA512_H
#define SHA512_H
-#define SHA512_BLOCK_LENGTH 128
-#define SHA512_DIGEST_LENGTH 64
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
#include <stdlib.h>
-typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
+typedef uint8_t __attribute__((aligned(8))) \
+ sha2_hash_t[ SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
-typedef uint8_t sha2_byte; /* Exactly 1 byte */
-typedef uint32_t sha2_word32; /* Exactly 4 bytes */
-typedef uint64_t sha2_word64; /* Exactly 8 bytes */
+typedef uint8_t sha2_byte; /* Exactly 1 byte */
+typedef uint32_t sha2_word32; /* Exactly 4 bytes */
+typedef uint64_t sha2_word64; /* Exactly 8 bytes */
-typedef struct _SHA512_CTX {
- uint64_t state[8];
- uint64_t bitcount[2];
- uint8_t buffer[SHA512_BLOCK_LENGTH];
+typedef struct _SHA512_CTX
+{
+ uint64_t state[8];
+ uint64_t bitcount[2];
+ uint8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
+extern "C"
void SHA512_Init(SHA512_CTX* context);
+extern "C"
void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len);
+extern "C"
void SHA512_Final(SHA512_CTX* context, sha2_hash_t *result);
-
+extern "C"
void SHA512_Hash(const sha2_byte *data, size_t len, sha2_hash_t *result);
#endif
diff --git a/src/include/securerom/status_codes.H b/src/include/securerom/status_codes.H
index a2f94f597..8b9edba54 100644
--- a/src/include/securerom/status_codes.H
+++ b/src/include/securerom/status_codes.H
@@ -22,9 +22,7 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/****************************************************************************
- *
- ****************************************************************************/
+
#ifndef STATUS_CODES_H
#define STATUS_CODES_H
@@ -36,16 +34,9 @@
#endif
// context codes
-#define ROM_INSTRUCTION_START 0x0100
-#define C_INSTRUCTION_START 0x0200
-#define ROM_SELFTEST 0x0300
-#define ROM_VERIFY 0x0400
-// documentaion 0x0600 C_INSTRUCTION_START call of ROM_VERIFY
+#define ROM_VERIFY 0x0100
#define ROM_SRESET 0x0E00
-#define PHYP_VERIFY 0x1500
-#define PHYP_SHA512_HASH 0x1600
-
// progress/test codes
#define BEGIN 0x0001
@@ -70,7 +61,6 @@
#define SHA_BAD_TEST 0x0041
#define ECDSA_GOOD_TEST 0x0042
#define ECDSA_BAD_TEST 0x0043
-#define SELFTEST_DONE 0x0044
#define TARGET_LOW_TEST 0x0050
#define TARGET_VALID_TEST 0x0051
@@ -91,9 +81,8 @@
#define HW_SIGNATURE_TEST 0x0061
#define PREFIX_ECID_TEST 0x0062
#define PREFIX_HASH_TEST 0x0063
-#define SPECIAL_NO_ECID_TEST 0x0064
-#define SPECIAL_SIZE_0_TEST 0x0065
-#define SW_KEY_PROTECTION_TEST 0x0066
+#define SW_KEY_PROTECTION_TEST 0x0064
+#define SW_KEY_INVALID_COUNT 0x0065
#define SW_SIGNATURE_TEST 0x0070
#define HEADER_ECID_TEST 0x0071
diff --git a/src/lib/makefile b/src/lib/makefile
index 47076f964..5fdf78ac8 100644
--- a/src/lib/makefile
+++ b/src/lib/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2010,2015
+# Contributors Listed Below - COPYRIGHT 2010,2017
# [+] International Business Machines Corp.
#
#
@@ -26,6 +26,7 @@ ROOTPATH = ../..
OBJS += string.o
OBJS += string_ext.o
+OBJS += string_utils.o
OBJS += stdlib.o
OBJS += ctype.o
OBJS += assert.o
diff --git a/src/lib/string.C b/src/lib/string.C
index 9acc418e7..004345372 100644
--- a/src/lib/string.C
+++ b/src/lib/string.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,106 +25,11 @@
#include <string.h>
#include <stdlib.h>
-extern "C" void *memset(void *vdest, int ch, size_t len)
-{
- // TODO: align to an 8-byte boundary
- // Loop, storing 8 bytes every 3 instructions
- long *ldest = reinterpret_cast<long *>(vdest);
- if (len >= sizeof(long))
- {
- long lch = ch & 0xFF;
- lch |= lch<<8;
- lch |= lch<<16;
- lch |= lch<<32;
- size_t len8 = len / sizeof(long);
- size_t i = len8;
- do
- {
- ldest[--i] = lch;
- }
- while( i > 0 );
- ldest += len8;
- len -= len8 * sizeof(long);
- }
-
- // Loop, storing 1 byte every 3 instructions
- char *cdest = reinterpret_cast<char *>(ldest);
- while (len >= sizeof(char))
- {
- *cdest++ = ch;
- len -= sizeof(char);
- }
-
- return vdest;
-}
-
extern "C" void bzero(void *vdest, size_t len)
{
memset(vdest, 0, len);
}
-extern "C" void *memcpy(void *vdest, const void *vsrc, size_t len)
-{
- // TODO: align to an 8-byte boundary?
-
- // Loop, copying 8 bytes every 5 instructions (TODO: 8/4 should be possible)
- long *ldest = reinterpret_cast<long *>(vdest);
- const long *lsrc = reinterpret_cast<const long *>(vsrc);
-
- while (len >= sizeof(long))
- {
- *ldest++ = *lsrc++;
- len -= sizeof(long);
- }
-
- // Loop, copying 1 byte every 4 instructions
- char *cdest = reinterpret_cast<char *>(ldest);
- const char *csrc = reinterpret_cast<const char *>(lsrc);
- for (size_t i = 0; i < len; ++i)
- {
- cdest[i] = csrc[i];
- }
-
- return vdest;
-}
-
-extern "C" void *memmove(void *vdest, const void *vsrc, size_t len)
-{
- // Copy first-to-last
- if (vdest <= vsrc)
- {
- return memcpy(vdest,vsrc,len);
- }
-
- // Copy last-to-first (TO_DO: optimize)
- char *dest = reinterpret_cast<char *>(vdest);
- const char *src = reinterpret_cast<const char *>(vsrc);
- for (size_t i = len; i > 0;)
- {
- --i;
- dest[i] = src[i];
- }
-
- return vdest;
-}
-
-extern "C" int memcmp(const void *p1, const void *p2, size_t len)
-{
- const char *c1 = reinterpret_cast<const char *>(p1);
- const char *c2 = reinterpret_cast<const char *>(p2);
-
- for (size_t i = 0; i < len; ++i)
- {
- long n = static_cast<long>(c1[i]) - static_cast<long>(c2[i]);
- if (n != 0)
- {
- return n;
- }
- }
-
- return 0;
-}
-
extern "C" void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen)
{
diff --git a/src/lib/string_utils.C b/src/lib/string_utils.C
new file mode 100644
index 000000000..2ef8419a9
--- /dev/null
+++ b/src/lib/string_utils.C
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/lib/string_utils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" void *memset(void *vdest, int ch, size_t len)
+{
+ // TODO: align to an 8-byte boundary
+ // Loop, storing 8 bytes every 3 instructions
+ long *ldest = reinterpret_cast<long *>(vdest);
+ if (len >= sizeof(long))
+ {
+ long lch = ch & 0xFF;
+ lch |= lch<<8;
+ lch |= lch<<16;
+ lch |= lch<<32;
+ size_t len8 = len / sizeof(long);
+ size_t i = len8;
+ do {
+ ldest[--i] = lch;
+ } while( i > 0 );
+ ldest += len8;
+ len -= len8 * sizeof(long);
+ }
+
+ // Loop, storing 1 byte every 3 instructions
+ char *cdest = reinterpret_cast<char *>(ldest);
+ while (len >= sizeof(char))
+ {
+ *cdest++ = ch;
+ len -= sizeof(char);
+ }
+
+ return vdest;
+}
+
+extern "C" void *memcpy(void *vdest, const void *vsrc, size_t len)
+{
+ // TODO: align to an 8-byte boundary?
+
+ // Loop, copying 8 bytes every 5 instructions (TODO: 8/4 should be possible)
+ long *ldest = reinterpret_cast<long *>(vdest);
+ const long *lsrc = reinterpret_cast<const long *>(vsrc);
+
+ while (len >= sizeof(long))
+ {
+ *ldest++ = *lsrc++;
+ len -= sizeof(long);
+ }
+
+ // Loop, copying 1 byte every 4 instructions
+ char *cdest = reinterpret_cast<char *>(ldest);
+ const char *csrc = reinterpret_cast<const char *>(lsrc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ cdest[i] = csrc[i];
+ }
+
+ return vdest;
+}
+
+extern "C" void *memmove(void *vdest, const void *vsrc, size_t len)
+{
+ // Copy first-to-last
+ if (vdest <= vsrc)
+ {
+ return memcpy(vdest,vsrc,len);
+ }
+
+ // Copy last-to-first (TO_DO: optimize)
+ char *dest = reinterpret_cast<char *>(vdest);
+ const char *src = reinterpret_cast<const char *>(vsrc);
+ for (size_t i = len; i > 0;)
+ {
+ --i;
+ dest[i] = src[i];
+ }
+
+ return vdest;
+}
+
+extern "C" int memcmp(const void *p1, const void *p2, size_t len)
+{
+ const char *c1 = reinterpret_cast<const char *>(p1);
+ const char *c2 = reinterpret_cast<const char *>(p2);
+
+ for (size_t i = 0; i < len; ++i)
+ {
+ long n = static_cast<long>(c1[i]) - static_cast<long>(c2[i]);
+ if (n != 0)
+ {
+ return n;
+ }
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/makefile b/src/makefile
index ef0520df8..625e103f0 100644
--- a/src/makefile
+++ b/src/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2010,2016
+# Contributors Listed Below - COPYRIGHT 2010,2017
# [+] Google Inc.
# [+] International Business Machines Corp.
#
@@ -34,6 +34,7 @@ SUBDIRS += sys.d
SUBDIRS += usr.d
SUBDIRS += build.d
SUBDIRS += runtime.d
+SUBDIRS += securerom.d
# Reducing HB extended img size for VPO by disabling certain libs using
# CONFIG_VPO_COMPILE option
@@ -42,9 +43,11 @@ IMGS += hbicore
IMGS += hbicore_test
IMGS += hbirt
IMGS += hbirt_test
+IMGS += securerom
BASE_OBJECTS += string.o
BASE_OBJECTS += string_ext.o
+BASE_OBJECTS += string_utils.o
BASE_OBJECTS += ctype.o
BASE_OBJECTS += math.o
BASE_OBJECTS += builtins.o
@@ -70,6 +73,13 @@ BOOTLDR_OBJECTS += bl_pnor_ecc.o
BOOTLDR_OBJECTS += bl_terminate.o
BOOTLDR_OBJECTS += forceattn_p8.o
+SECUREROM_OBJECTS += branchtable.o
+SECUREROM_OBJECTS += ROM.o
+SECUREROM_OBJECTS += ecverify.o
+SECUREROM_OBJECTS += hw_utils.o
+SECUREROM_OBJECTS += sha512.o
+SECUREROM_OBJECTS += string_utils.o
+
DIRECT_BOOT_OBJECTS += start.o
DIRECT_BOOT_OBJECTS += kernel.o
DIRECT_BOOT_OBJECTS += taskmgr.o
@@ -303,6 +313,7 @@ RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
hbibl_OBJECTS += ${BL_BASE_OBJECTS}
hbibl_OBJECTS += ${BOOTLDR_OBJECTS}
hbibl_LDFILE = bootloader.ld
+hbibl_NO_RELOCATION = 1
hbicore_OBJECTS += ${BASE_OBJECTS}
hbicore_OBJECTS += ${DIRECT_BOOT_OBJECTS}
@@ -310,6 +321,10 @@ hbicore_MODULES += ${BASE_MODULES}
hbicore_EXTENDED_MODULES += ${EXTENDED_MODULES}
hbicore_LDFILE = kernel.ld
+securerom_OBJECTS += ${SECUREROM_OBJECTS}
+securerom_LDFILE = securerom.ld
+securerom_NO_RELOCATION = 1
+
# for PRDR_RULE_TABLE_TARGETS
include ${ROOTPATH}/src/usr/diag/prdf/common/rule/prdf_rule.mk
diff --git a/src/securerom.ld b/src/securerom.ld
index 10670afe9..4159440a6 100644
--- a/src/securerom.ld
+++ b/src/securerom.ld
@@ -22,75 +22,53 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/*****************************************************************************/
-/* linker script for low level firmware */
-/*****************************************************************************/
-
-/* PH: to use the same lds file for 32/64bit, don't specify
- * OUTPUT_FORMAT, OUTPUT_ARCH here.
- * /
- OUTPUT_FORMAT("elf64-powerpc")
- OUTPUT_ARCH(powerpc64:common)
- */
-
-/* set the entry point */
-ENTRY(_instruction_start)
-
-MEMORY {
- secure_boot_rom (IRX): ORIGIN = 0x80001C0000000000, LENGTH = 32K
-/* untrusted_memory (RW): ORIGIN = 0x8000000000000000, LENGTH = 0x0000000000800000
-* trusted_memory (RW): ORIGIN = 0x8000000000800000, LENGTH = 0x800000FFFF800000
-*/
-}
-
SECTIONS {
- . = 0x80001C0000000000; /* tbrom base address */
-
- .branchtable : {
- . = ALIGN(0x1000);
- }>secure_boot_rom
-
- .text : {
- *(.text)
- }>secure_boot_rom
+ .text : {
+ *(.branchtable)
+ *(.text)
+ *(.text._*)
+ *(.text.*)
+ *(.sfpr)
+ }
- . = ALIGN(8);
+ .rodata ALIGN(0x8): {
+ *(.rodata)
+ *(.rodata.*)
+ . = ALIGN(8);
+ __toc_start = .;
+ *(.toc)
+ *(.opd)
+ *(.got)
+ *(.plt)
+ *(.data.rel.ro.*)
+ }
- __toc_start = .;
- .toc : {
- *(.toc .got)
- }>secure_boot_rom
- . = ALIGN(8);
- __toc_end = .;
+ .data ALIGN(0x8): {
+ *(.data)
+ *(.data.*)
+ *(.got1)
+ *(.sdata)
+ *(.bss)
+ *(.bss.*)
+ }
- .data : {
- *(.data)
- *(.rodata .rodata.*)
- *(.got1)
- *(.sdata)
- }>secure_boot_rom
+ end_load_address = .;
- . = ALIGN(8);
+ .rela : {
+ *(.rela.*)
+ }
- /* PH: opd section must be separate, if i put it in .data,
- * the C functions are not present in the generated file....
- * If anybody can explain why, i'd be glad to hear...
- * Note: the KEEP has been removed was: " KEEP (*(.opd)) "
- */
- .opd ALIGN(8) : {
- *(.opd)
- }>secure_boot_rom
-
- . = ALIGN(8);
- __bss_start = .;
- .bss : {
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- }>secure_boot_rom
- . = ALIGN(8);
- __bss_end = .;
- __bss_size = SIZEOF(.bss);
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .eh_frame : { *(.eh_frame) }
+ /DISCARD/ : {
+ *(.comment)
+ *(.gnu.attributes)
+ *(.dtors)
+ *(.interp)
+ }
}
diff --git a/src/securerom/ROM.C b/src/securerom/ROM.C
index 2f73a5da5..bb1438772 100644
--- a/src/securerom/ROM.C
+++ b/src/securerom/ROM.C
@@ -22,558 +22,209 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/****************************************************************************
- *
- ****************************************************************************/
-#ifndef PHYPLIBFUNCTIONS
-#include <ROM.h>
-#endif
-#include <ecverify.h>
-#include <status_codes.h>
-#include <string.h>
-
-/****************************************************************************/
-#define valid_magic_number(header) (GET32((header)->magic_number) == ROM_MAGIC_NUMBER)
-#define valid_container_version(header) (GET16((header)->version) == CONTAINER_VERSION)
-
-/****************************************************************************/
-static int valid_ver_alg(ROM_version_raw* ver_alg, uint8_t sig_alg) {
- if (GET16(ver_alg->version) != HEADER_VERSION) return 0;
- if (ver_alg->hash_alg != HASH_ALG_SHA512) return 0;
- if (!sig_alg) return 1;
- if (ver_alg->sig_alg != sig_alg) return 0;
- return 1;
-}
-
-/****************************************************************************/
-static int valid_ecid(int ecid_count, uint8_t* ecids, uint8_t* hw_ecid) {
- if (!ecid_count) return 1;
- for (;ecid_count;ecid_count--,ecids+=ECID_SIZE)
- if (!memcmp (hw_ecid, ecids, ECID_SIZE)) return 1;
- return 0;
-}
-/****************************************************************************/
-static int multi_key_verify(uint8_t* digest, int key_count, uint8_t* keys, uint8_t* sigs) {
- for (;key_count;key_count--,keys+=sizeof(ecc_key_t),sigs+=sizeof(ecc_signature_t))
- if (ec_verify (keys, digest, sigs)<1) return 0;
- return 1;
-}
-
-#ifndef PHYPLIBFUNCTIONS
-/****************************************************************************/
-static inline ROM_container_raw* cast_container(uint64_t addr) {
- return (ROM_container_raw*) Convert_Mem_Addr(physical_addr(addr));
-}
-
-/****************************************************************************/
-static inline void ROM_init_cache_area(uint64_t target, uint64_t size) {
- uint64_t i;
- for (i=0;i<size;i+=CACHE_LINE) {
- assem_DCBZ(target);
- target+=CACHE_LINE;
- }
-}
+#include <securerom/ROM.H>
+#include <securerom/ecverify.H>
+#include <securerom/status_codes.H>
+#include <string.h>
-/****************************************************************************/
-//static inline void ROM_invalidate_cache_area(uint64_t target, uint64_t size) {
-// uint64_t i;
-// for (i=0;i<size;i+=CACHE_LINE) {
-// assem_DCBI(target);
-// target+=CACHE_LINE;
-// }
-//}
+#define valid_magic_number(header) \
+ (GET32((header)->magic_number) == ROM_MAGIC_NUMBER)
+#define valid_container_version(header) \
+ (GET16((header)->version) == CONTAINER_VERSION)
-/****************************************************************************/
-static void ROM_memcpy_icbi (uint64_t* to, uint64_t* from, int64_t size) {
- uint64_t* src=from;
- uint64_t* dst=to;
- for(;size>0;size-=sizeof(uint64_t)) {
- *dst++ = *src++;
- }
- assem_SYNC(); //heavy weight form of sync instruction
- //which ensures all stores have been performed
- //prior to the subsequent icbi
- assem_ICBI(to); //only need one of these to any address....
- //this is only needed to set internal scoreboard bit
- //to tell the processor to flush
- //when it sees a subsequent isync
- assem_ISYNC();
+static int valid_ver_alg(ROM_version_raw* ver_alg, uint8_t sig_alg)
+{
+ if (GET16(ver_alg->version) != HEADER_VERSION)
+ {
+ return 0;
+ }
+ if (ver_alg->hash_alg != HASH_ALG_SHA512)
+ {
+ return 0;
+ }
+ if (!sig_alg)
+ {
+ return 1;
+ }
+ if (ver_alg->sig_alg != sig_alg)
+ {
+ return 0;
+ }
+ return 1;
}
-//extern void* __toc_start;
-
-#if 0
-
-#define STACK_ASSUMPTION 128*1024
-#define STACK_FRAME (2*8)
-/****************************************************************************/
-#undef CONTEXT
-#define CONTEXT ROM_INSTRUCTION_START
-/****************************************************************************/
-static inline void Create_C_Environment(uint64_t stack) {
- #ifdef EMULATE_HW
- printf ("Creating C Environment with stack pointer 0x%016llX\n",stack);
- #else
- // zero (create) stack area
- ROM_init_cache_area(stack-STACK_ASSUMPTION, STACK_ASSUMPTION);
- LOG(STACK_ZERO_DONE);
-
- // set stackpointer
- register volatile uint64_t r1 __asm__ ("r1"); // if you remove the volatile keyword then the compiler removes your code - grr
- r1 = stack-8;
- //*((uint64_t*)stack) = 0ull; -- end stackframe --already 0 by dcbz above
-
- //setup initial stackframe
- asm("stdu r1, -56(r1)");
-
- #endif
+static int valid_ecid(int ecid_count, uint8_t* ecids, uint8_t* hw_ecid)
+{
+ if (ecid_count == 0)
+ {
+ return 1;
+ }
+ return 0;
}
-static inline void initTOCpointer() {
- #ifdef EMULATE_HW
- printf ("Initialize r2 with TOC pointer\n");
- #else
- // set TOC pointer (unused because no global variables)
- // register uint64_t r2 __asm__ ("r2");
- // r2 = (uint64_t)__toc_start+0x8000; //only for one TOC
- // r2 = ((uint64_t*)&ROM_instruction_start)[1]; //saver to get from { entry_point, toc_base, environment }
- asm(
- "springboard2: \n"
- " b boingboing2 \n" // set CFAR
- "boingboing2: \n"
- " mfspr r2, 28 \n" // mfCFAR get address of springboard2
- " addi r2, r2, 0x4000 \n" // adjust to __toc_start (part 1)
- " addi r2, r2, (__toc_start+0x4000-springboard2)@l \n" // adjust to __toc_start (part 2)
- );
- #endif
+static int multi_key_verify(uint8_t* digest, int key_count, uint8_t* keys,
+ uint8_t* sigs)
+{
+ for (;key_count;key_count--,keys+=sizeof(ecc_key_t),
+ sigs+=sizeof(ecc_signature_t))
+ {
+ if (ec_verify (keys, digest, sigs)<1)
+ {
+ return 0;
+ }
+ }
+ return 1;
}
-/****************************************************************************/
-#undef CONTEXT
-#define CONTEXT ROM_SELFTEST
-/****************************************************************************/
-static void ROM_selftest(void) {
-#ifndef EMULATE_HW
- selftest_t const *selftest_p;
- asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
- "sub %0,r2,%0 \n\t" // because subi does not work
- "addi %0,%0,(selftest-0x8000)@l" : "=r" (selftest_p) );
-#else
- selftest_t const *selftest_p = &selftest; //this line would introduce a absolute address in the toc
-#endif
-
- sha2_hash_t digest;
- LOG(BEGIN);
- // sha512 good selftest
- SHA512_Hash((uint8_t*)&selftest_p->ec, sizeof(selftest_p->ec), &digest);
- if(memcmp(digest, selftest_p->sha.hash, sizeof(sha2_hash_t)))
- ERROR_STOP(SHA_GOOD_TEST,"sha512 good selftest failed");
- // sha512 bad selftest
- SHA512_Hash((uint8_t*)&selftest_p->ec, sizeof(selftest_p->ec)-1, &digest);
- if(!memcmp (digest, selftest_p->sha.hash, sizeof(sha2_hash_t)))
- ERROR_STOP(SHA_BAD_TEST,"sha512 bad selftest failed");
- // ecdsa verify good selftest
- if (ec_verify (selftest_p->ec.pkey, selftest_p->ec.hash, selftest_p->ec.sig)<1)
- ERROR_STOP(ECDSA_GOOD_TEST,"ecdsa good selftest failed");
- // ecdsa verify bad selftest (use digest from sha512 bad test)
- if (ec_verify (selftest_p->ec.pkey, digest, selftest_p->ec.sig)!=0)
- ERROR_STOP(ECDSA_BAD_TEST,"ecdsa bad selftest failed");
+static inline ROM_container_raw* cast_container(uint64_t addr)
+{
+ return (ROM_container_raw*) Convert_Mem_Addr(physical_addr(addr));
}
-/****************************************************************************/
-#undef CONTEXT
-#define CONTEXT C_INSTRUCTION_START
-/****************************************************************************/
-uint64_t C_instruction_start( uint64_t xscom
- , uint64_t fsp_bar
- , uint64_t stack
- , ROM_container_raw* container
- ) {
- LOG(BEGIN);
-
- // run crypto selftests
- ROM_selftest();
- LOG(SELFTEST_DONE);
-
- // test for valid target hrmor address in trusted memory (security checks)
- uint64_t target_hrmor = GET64(container->target_hrmor);
- if(target_hrmor < 4096)
- ERROR_STOP(TARGET_LOW_TEST,"target hrmor too low");
- if(target_hrmor & ~HRMOR_MASK)
- ERROR_STOP(TARGET_VALID_TEST,"invalid target hrmor address");
- if(physical_addr(target_hrmor-4096)<fsp_bar)
- ERROR_STOP(TARGET_TRUST_TEST,"target hrmor in untrusted memory");
- target_hrmor = ABSOLUTE_ADDR(target_hrmor); //WEH bug fix, moved to allow previous test to work
-
- // test for stack and container collision
- uint64_t size = GET64(container->container_size);
- if( stack > target_hrmor-4096
- && stack-STACK_ASSUMPTION <= target_hrmor+size
- )
- ERROR_STOP(STACK_VS_TARGET_TEST,"container vs stack collision");
-
- mtspr_HRMOR(target_hrmor);
-
- // clear ERATS because hrmor has changed
- #ifdef EMULATE_HW
- printf ("clear ERATS because hrmor has changed\n");
- #else
- asm volatile ("slbia");
- #endif
-
- // zero target area and copy container
- ROM_init_cache_area(target_hrmor-4096, size);
- LOG(TARGET_ZERO_DONE);
- ROM_container_raw* target = cast_container(target_hrmor-4096);
- ROM_memcpy_icbi((uint64_t*)target, (uint64_t*)container, size);
- LOG(CONTAINER_COPY_DONE);
-
- // test for prefix header with HBI base code (firmware) signing keys
- ROM_prefix_header_raw* prefix = (ROM_prefix_header_raw*) &target->prefix;
- if(!valid_ver_alg(&prefix->ver_alg, SIG_ALG_ECDSA521))
- ERROR_STOP(PREFIX_VER_ALG_TEST,"bad prefix header version,alg's");
- uint32_t flags = GET32 (prefix->flags);
- if(!(flags & HBI_BASE_SIGNING_KEY))
- ERROR_STOP(HBI_KEY_TEST,"not HBI base code key prefix");
-
- // verify
-
- // fill verify hw params
- ROM_hw_params params;
- getscom_PIBMEM_HW_Key_Hash(xscom, params.hw_key_hash);
- getscom_HW_ECID(xscom, params.my_ecid);
- if (ROM_verify(target,&params) != ROM_DONE)
- ERROR_STOP(params.log,"see above"); // this will added C_INSTRUCTION_START to ROM_VERIFY for 0600
- LOG(CONTAINER_VERIFY_DONE);
-
- return HRMOR_RELATIVE(params.entry_point);
+static inline void ROM_init_cache_area(uint64_t target, uint64_t size)
+{
+ uint64_t i;
+ for (i=0;i<size;i+=CACHE_LINE)
+ {
+ assem_DCBZ(target);
+ target+=CACHE_LINE;
+ }
}
-#endif
-
-/****************************************************************************/
#undef CONTEXT
#define CONTEXT ROM_SRESET
-/****************************************************************************/
-#ifdef EMULATE_HW
-void ROM_sreset (void) {
-#else
-void ROM_sreset(void) {
- asm volatile (".globl rom_sreset\n rom_sreset:"); //skip prologue
-#endif
- // should never get here unless started too soon by fsp/sbe, checkstop
- ERROR_STOP(EXECUTION_ERROR,"sreset");
-}
-
-#if 0
-/****************************************************************************/
-#undef CONTEXT
-#define CONTEXT ROM_INSTRUCTION_START
-/****************************************************************************/
-//static inline void ROM_Cleanup_Stack(uint64_t stack) {
-//#ifdef EMULATE_HW
-// printf ("Cleaning up stack\n");
-//#endif
-// ROM_invalidate_cache_area(stack-STACK_ASSUMPTION, STACK_ASSUMPTION);
-//}
-
-/****************************************************************************/
-#ifdef EMULATE_HW
-static void Call_Entry_Point(uint64_t start) {
- printf ("Branching to entry point 0x%016llX (PHY 0x%016llX)\n",start,physical_addr(start));
- return;
-#else
-static void __attribute__((noreturn)) Call_Entry_Point(uint64_t start) {
-
- asm volatile ( " mtctr %0 \n"
- " bctr \n"
- " nop "
- : // no output
- : "r" (start) // input, %0
- // no impacts ?
- );
-
- ERROR_STOP(RETURNED_ERROR,"returned from Entry_Point");
- #if !defined(_lint_)
- for (;;);
- #endif
-#endif
-}
-
-/* Check the maximum limit of a untrusted memory BAR
- *
- * A BAR are two SCOM register one containing a mask and the other the pattern
- * the address is in the untrusted memory when this is true:
- * (address & mask) == pattern
- * If this is true then a untrusted PIB master (like FSI) can write it.
- * Remark:
- * If a mask bit is 0 and the coresponding pattern bit is 1 then it is always false.
- *
- * parameter:
- * limit = previous limit from other BARs or 0
- * xscom = the xscom base address
- * bar = the pib address of the BAR register containing the pattern
- * barMask = the pib address of the BAR register containing the mask
- * return value:
- * the new limit is the maximum from previous limit and the bars limit
- */
-uint64_t check_bar(uint64_t limit, uint64_t xscom, uint64_t bar, uint64_t barMask) {
- uint64_t barValue = getscom(xscom,bar);
- uint64_t barMaskValue = getscom(xscom,barMask);
-
- barMaskValue |= 0xFFFC000000000000; // bit 0:13 not implemented and must be '1'
-
- uint64_t barLimit = (barValue | ~barMaskValue) + 1;
- if( ( (barValue & ~barMaskValue) == 0)
- && ( barLimit > limit)
- ) {
- limit=barLimit;
- }
- return limit;
-}
-
-#endif
-
-/****************************************************************************/
#ifdef EMULATE_HW
-void ROM_instruction_start(void) {
-#else
-void __attribute__((noreturn)) ROM_instruction_start(void) {
- asm volatile (".globl instruction_start\ninstruction_start:"); //skip prologue
-#endif
-
-#if 0
-
- initTOCpointer();
-
- LOG(BEGIN);
-
- // test for reasonable xscom base address (security check)
- register uint64_t xscom = mfspr_SCRATCH0();
- if(!xscom) {
- ERROR_STOP(XSCOM_LOW_TEST,"xscom base address too low");
- }
- if(xscom & ~XSCOM_MASK) {
- ERROR_STOP(XSCOM_VALID_TEST,"invalid xscom base address");
- }
- xscom = ABSOLUTE_ADDR(xscom);
-
-#ifndef EMULATE_HW
- // get trusted memory base
- uint64_t fsp_bar=0;
- fsp_bar = check_bar(fsp_bar, xscom, ALTD_UNTRUSTED_BAR_ADDR_REG, ALTD_UNTRUSTED_BAR_MASK_ADDR_REG);
- fsp_bar = check_bar(fsp_bar, xscom, PSIHB_NOTRUST_BAR0, PSIHB_NOTRUST_BAR0MASK );
- fsp_bar = check_bar(fsp_bar, xscom, PSIHB_NOTRUST_BAR1, PSIHB_NOTRUST_BAR1MASK );
+void ROM_sreset (void)
+{
#else
- // get trusted memory base
- uint64_t fsp_bar = (getscom_FSP_BAR_value(xscom) | ~getscom_FSP_BAR_mask(xscom)) + 1;
+void ROM_sreset(void)
+{
+ asm volatile (".globl rom_sreset\n rom_sreset:"); //skip prologue
#endif
-
- LOG(TRUSTED_MEM_BAR);
-
- register uint64_t raw_container = mfspr_SCRATCH1();
- if (raw_container < 4096) //must check for value that will wrap around
- ERROR_STOP(CONTAINER_LOW_TEST,"container too low");
- raw_container = ABSOLUTE_ADDR(raw_container)-4096;
- ROM_container_raw* container = cast_container(raw_container);
-
- // test for valid container magic number, version, hash & signature algorithms (sanity checks)
- if(!valid_magic_number(container))
- ERROR_STOP(MAGIC_NUMBER_TEST,"bad container magic number");
- if (!valid_container_version (container))
- ERROR_STOP(CONTAINER_VERSION_TEST,"bad container version");
-
- // test for trusted memory stack pointer (assumes 8K max depth)
- register uint64_t stack = GET64(container->stack_pointer);
- stack += STACK_ASSUMPTION;
- if(stack < STACK_ASSUMPTION) {
- ERROR_STOP(STACK_LOW_TEST,"stack pointer too low");
- }
- if(stack & ~STACK_MASK)
- ERROR_STOP(STACK_VALID_TEST,"invalid stack pointer address");
- if(physical_addr(stack-STACK_ASSUMPTION)<fsp_bar)
- ERROR_STOP(STACK_TRUST_TEST,"stack in untrusted memory");
- stack = ABSOLUTE_ADDR(stack); //WEH bug fix, moved to allow previous test to work
-
- // launch C environment (zero stack)
- Create_C_Environment(stack);
-
- // Jump to C code
- register uint64_t entry = C_instruction_start(xscom,fsp_bar,stack,container);
-
- // cleanup (invalidate) stack - no longer required HBI takes care
- //ROM_Cleanup_Stack(stack);
- //LOG(STACK_CLEANUP_DONE);
-
- // clear scratch 0 and 1 reg - no longer required
- //mtspr_SCRATCH0(0);
- //mtspr_SCRATCH1(0);
-
- LOG(COMPLETED);
- Call_Entry_Point(entry); // never return from here!!!
- #endif
+ // should never get here unless started too soon by fsp/sbe, checkstop
+ ERROR_STOP(EXECUTION_ERROR,"sreset");
}
-/****************************************************************************/
-#endif
-
#ifdef EMULATE_HW
- #define FAILED(_c,_m) { params->log=ERROR_EVENT|CONTEXT|(_c); printf ("FAILED '%s'\n", (_m)); return ROM_FAILED; }
+ #define FAILED(_c,_m) { params->log=ERROR_EVENT|CONTEXT|(_c); \
+ printf ("FAILED '%s'\n", (_m)); return ROM_FAILED; }
#else
- #define FAILED(_c,_m) { params->log=ERROR_EVENT|CONTEXT|(_c); return ROM_FAILED; }
+ #define FAILED(_c,_m) { params->log=ERROR_EVENT|CONTEXT|(_c); \
+ return ROM_FAILED; }
#endif
-//****************************************************************************
#undef CONTEXT
-#ifndef PHYPLIBFUNCTIONS
#define CONTEXT ROM_VERIFY
-//****************************************************************************
-// NOTE: ROM_verify is called with absolute addresses from c_instruction_start
-// and with hrmor relative addresses from Hostboot
+// NOTE: ROM_verify is called with with hrmor relative addresses from Hostboot
asm(".globl .L.ROM_verify");
ROM_response ROM_verify( ROM_container_raw* container,
- ROM_hw_params* params ) {
-#else
-#define CONTEXT PHYP_VERIFY
-//****************************************************************************
-// NOTE: PHYP_verify is called with hrmor relative addresses from PHYP
-ROM_response PHYP_verify( PHYP_command cmnd,
- ROM_container_raw* container,
- PHYP_hw_params* params,
- PHYP_verify_state* state ) {
-#endif
- sha2_hash_t digest;
- ROM_prefix_header_raw* prefix;
- ROM_prefix_data_raw* hw_data;
- ROM_sw_header_raw* header;
- ROM_sw_sig_raw* sw_sig;
- uint64_t size;
-
- params->log=CONTEXT|BEGIN;
-
-#ifdef PHYPLIBFUNCTIONS
- if(cmnd != PHYP_CONTINUE) {
-#endif
- // test for valid container magic number, version, hash & signature algorithms (sanity check)
+ ROM_hw_params* params )
+{
+ sha2_hash_t digest;
+ ROM_prefix_header_raw* prefix;
+ ROM_prefix_data_raw* hw_data;
+ ROM_sw_header_raw* header;
+ ROM_sw_sig_raw* sw_sig;
+ uint64_t size;
+
+ params->log=CONTEXT|BEGIN;
+
+ // test for valid container magic number, version, hash & signature
+ // algorithms (sanity check)
if(!valid_magic_number(container))
FAILED(MAGIC_NUMBER_TEST,"bad container magic number");
if(!valid_container_version(container))
FAILED(CONTAINER_VERSION_TEST,"bad container version");
-#ifdef PHYPLIBFUNCTIONS
- // initialize verify state
- state->state = PHYP_START_VERIFY;
- }
- do {
- switch(state->state) {
- case PHYP_START_VERIFY:
-#endif
- // process hw keys
- // test for valid hw keys
- SHA512_Hash(container->hw_pkey_a, 3*sizeof(ecc_key_t), &digest);
- if(memcmp(params->hw_key_hash, digest, sizeof(sha2_hash_t)))
+ // process hw keys
+ // test for valid hw keys
+ SHA512_Hash(container->hw_pkey_a, 3*sizeof(ecc_key_t), &digest);
+ if(memcmp(params->hw_key_hash, digest, sizeof(sha2_hash_t)))
+ {
FAILED(HW_KEY_HASH_TEST,"invalid hw keys");
+ }
- // process prefix header
- prefix = (ROM_prefix_header_raw*) &container->prefix;
- // test for valid header version, hash & signature algorithms (sanity check)
- if(!valid_ver_alg(&prefix->ver_alg, SIG_ALG_ECDSA521))
+ // process prefix header
+ prefix = (ROM_prefix_header_raw*) &container->prefix;
+ // test for valid header version, hash & signature algorithms (sanity check)
+ if(!valid_ver_alg(&prefix->ver_alg, SIG_ALG_ECDSA521))
+ {
FAILED(PREFIX_VER_ALG_TEST,"bad prefix header version,alg's");
- // test for valid prefix header signatures (all)
- hw_data = (ROM_prefix_data_raw*) (prefix->ecid + prefix->ecid_count*ECID_SIZE);
- SHA512_Hash((uint8_t*)prefix, PREFIX_HEADER_SIZE(prefix), &digest);
- if(!multi_key_verify(digest, 3, container->hw_pkey_a, hw_data->hw_sig_a))
+ }
+ // test for valid prefix header signatures (all)
+ hw_data = (ROM_prefix_data_raw*) (prefix->ecid
+ + prefix->ecid_count*ECID_SIZE);
+ SHA512_Hash((uint8_t*)prefix, PREFIX_HEADER_SIZE(prefix), &digest);
+ if(!multi_key_verify(digest, 3, container->hw_pkey_a, hw_data->hw_sig_a))
+ {
FAILED(HW_SIGNATURE_TEST,"invalid hw signature");
- // test for machine specific matching ecid
- if(!valid_ecid(prefix->ecid_count, prefix->ecid, params->my_ecid))
+ }
+ // test for machine specific matching ecid
+ if(!valid_ecid(prefix->ecid_count, prefix->ecid, params->my_ecid))
+ {
FAILED(PREFIX_ECID_TEST,"unauthorized prefix ecid");
- // test for valid prefix payload hash
- size = GET64(prefix->payload_size);
- SHA512_Hash(hw_data->sw_pkey_p, size, &digest);
- if(memcmp(prefix->payload_hash, digest, sizeof(sha2_hash_t)))
+ }
+ // test for valid prefix payload hash
+ size = GET64(prefix->payload_size);
+ SHA512_Hash(hw_data->sw_pkey_p, size, &digest);
+ if(memcmp(prefix->payload_hash, digest, sizeof(sha2_hash_t)))
+ {
FAILED(PREFIX_HASH_TEST,"invalid prefix payload hash");
- // test for special prefix header
- if(!prefix->sw_key_count) {
- // finish processing special prefix header
- // test for machine specfic (sanity check)
- if(prefix->ecid_count == 0)
- FAILED(SPECIAL_NO_ECID_TEST,"special prefix with ecid_count == 0");
- // test for signing of keys only (sanity check)
- if(size != 0)
- FAILED(SPECIAL_SIZE_0_TEST,"special prefix with payload_size != 0");
- // return hrmor relative code start address
- params->entry_point = GET64(prefix->code_start_offset);
- //check if the entry is HRMOR-relative and aligned
- if(params->entry_point & ~(ENTRY_MASK))
- FAILED(ENTRY_VALID_TEST,"entry is not HRMOR relative or not aligned");
- params->log=CONTEXT|COMPLETED;
- return ROM_DONE;
- }
- // finish processing prefix header
- // test for protection of all sw key material (sanity check)
- if(size != (prefix->sw_key_count * sizeof(ecc_key_t)))
+ }
+ // test for valid sw key count
+ if (prefix->sw_key_count < 1 || prefix->sw_key_count > 3)
+ {
+ FAILED(SW_KEY_INVALID_COUNT,"sw key count not between 1-3");
+ }
+ // finish proce`sing prefix header
+ // test for protection of all sw key material (sanity check)
+ if(size != (prefix->sw_key_count * sizeof(ecc_key_t)))
+ {
FAILED(SW_KEY_PROTECTION_TEST,"incomplete sw key protection in prefix header");
+ }
- // start processing sw header
- header = (ROM_sw_header_raw*) (hw_data->sw_pkey_p + prefix->sw_key_count*sizeof(ecc_key_t));
- // test for valid header version, hash & signature algorithms (sanity check)
- if(!valid_ver_alg(&header->ver_alg, 0))
+ // start processing sw header
+ header = (ROM_sw_header_raw*) (hw_data->sw_pkey_p
+ + prefix->sw_key_count*sizeof(ecc_key_t));
+ // test for valid header version, hash & signature algorithms (sanity check)
+ if(!valid_ver_alg(&header->ver_alg, 0))
+ {
FAILED(HEADER_VER_ALG_TEST,"bad sw header version,alg");
- // test for valid sw header signatures (all)
- sw_sig = (ROM_sw_sig_raw*) (header->ecid + header->ecid_count*ECID_SIZE);
- SHA512_Hash((uint8_t*)header, SW_HEADER_SIZE(header), &digest);
- if(!multi_key_verify(digest, prefix->sw_key_count, hw_data->sw_pkey_p, sw_sig->sw_sig_p))
+ }
+ // test for valid sw header signatures (all)
+ sw_sig = (ROM_sw_sig_raw*) (header->ecid + header->ecid_count*ECID_SIZE);
+ SHA512_Hash((uint8_t*)header, SW_HEADER_SIZE(header), &digest);
+ if(!multi_key_verify(digest, prefix->sw_key_count, hw_data->sw_pkey_p,
+ sw_sig->sw_sig_p))
+ {
FAILED(SW_SIGNATURE_TEST,"invalid sw signature");
- // test for machine specific matching ecid
- if(!valid_ecid(header->ecid_count, header->ecid, params->my_ecid))
+ }
+ // test for machine specific matching ecid
+ if(!valid_ecid(header->ecid_count, header->ecid, params->my_ecid))
+ {
FAILED(HEADER_ECID_TEST,"unauthorized sw ecid");
- // test for entry point within protected payload (sanity check)
- params->entry_point = GET64(header->code_start_offset);
- //check if the entry is HRMOR-relative and aligned
- if(params->entry_point & ~(ENTRY_MASK))
- FAILED(ENTRY_VALID_TEST,"entry is not HRMOR relative or not aligned");
- size = GET64(header->payload_size);
- if(params->entry_point+3 >= size) // must have full instruction (3 more bytes)
+ }
+ // test for entry point within protected payload (sanity check)
+ params->entry_point = GET64(header->code_start_offset);
+ //check if the entry is HRMOR-relative and aligned
+ if(params->entry_point & ~(ENTRY_MASK))
+ {
+ FAILED(ENTRY_VALID_TEST,"entry is not HRMOR relative or not aligned");
+ }
+ size = GET64(header->payload_size);
+ // must have full instruction (3 more bytes)
+ if(params->entry_point+3 >= size)
+ {
FAILED(CODE_PROTECTION_TEST,"unprotected code_start in sw header");
- // begin test for valid sw payload hash
-#ifdef PHYPLIBFUNCTIONS
- state->message = (uint8_t*)container + 4096;
- state->remain = size;
- SHA512_Init(&state->sha);
- state->header = header;
- state->state = PHYP_CONT_VERIFY;
- params->log=CONTEXT|PARTIAL;
- break;
-
- case PHYP_CONT_VERIFY:
- if(state->remain > params->max_hash) {
- // continue test for valid sw payload hash
- SHA512_Update(&state->sha, state->message, params->max_hash);
- state->message += params->max_hash;
- state->remain -= params->max_hash;
- } else {
- // finish test for valid sw payload hash
- SHA512_Update(&state->sha, state->message, state->remain);
- SHA512_Final(&state->sha, &digest);
- header = state->header;
-#else
- SHA512_Hash((uint8_t*)container + 4096, size, &digest);
-#endif
- if(memcmp(header->payload_hash, digest, sizeof(sha2_hash_t)))
- FAILED(HEADER_HASH_TEST,"invalid sw payload hash");
- params->log=CONTEXT|COMPLETED;
- return ROM_DONE;
-#ifdef PHYPLIBFUNCTIONS
- }
- break;
+ }
+ // begin test for valid sw payload hash
+ SHA512_Hash((uint8_t*)container + 4096, size, &digest);
- default:
- FAILED(EXECUTION_ERROR,"bad internal state");
- break;
+ if(memcmp(header->payload_hash, digest, sizeof(sha2_hash_t)))
+ {
+ FAILED(HEADER_HASH_TEST,"invalid sw payload hash");
}
- } while (cmnd == PHYP_WHOLE);
- params->log=CONTEXT|PARTIAL;
- return PHYP_PARTIAL;
-#endif
+ params->log=CONTEXT|COMPLETED;
+ return ROM_DONE;
}
diff --git a/src/securerom/branchtable.S b/src/securerom/branchtable.S
index d3c1c8608..86a1f92a8 100644
--- a/src/securerom/branchtable.S
+++ b/src/securerom/branchtable.S
@@ -25,74 +25,68 @@
#****************************************************************************
#* branch table - a more stable location for software entering rom code
#****************************************************************************
-# adr function
-# 0 instruction_start
-# 2 .SHA512_Init
-# 4 .SHA512_Update
-# 6 .SHA512_Final
-# 8 .SHA512_Hash
-# A .ec_verify
-# C .ROM_verify
-# 100 rom_sreset
-branchtable:
- .section ".branchtable","ax"
+.include "kernel/ppcconsts.S"
- .globl _instruction_start
-_instruction_start:
- b instruction_start
- nop
+branchtable:
+ .section ".branchtable","ax"
- .globl _SHA512_Init
+ .globl _SHA512_Init
_SHA512_Init:
- li r0, .L.SHA512_Init@l
- b springboard
+ li r0, .L.SHA512_Init@l
+ b springboard
- .globl _SHA512_Update
+ .globl _SHA512_Update
_SHA512_Update:
- li r0, .L.SHA512_Update@l
- b springboard
+ li r0, .L.SHA512_Update@l
+ b springboard
- .globl _SHA512_Final
+ .globl _SHA512_Final
_SHA512_Final:
- li r0, .L.SHA512_Final@l
- b springboard
+ li r0, .L.SHA512_Final@l
+ b springboard
- .globl _SHA512_Hash
+ .globl _SHA512_Hash
_SHA512_Hash:
- li r0, .L.SHA512_Hash@l
- b springboard
+ li r0, .L.SHA512_Hash@l
+ b springboard
- .globl _ec_verify
+ .globl _ec_verify
_ec_verify:
- li r0, .L.ec_verify@l
- b springboard
+ li r0, .L.ec_verify@l
+ b springboard
- .globl _ROM_verify
+ .globl _ROM_verify
_ROM_verify:
- li r0, .L.ROM_verify@l
- b springboard
+ li r0, .L.ROM_verify@l
+ b springboard
#define CFAR 28
springboard:
- b boingboing
+ b boingboing
boingboing:
- mfspr r2, CFAR // get address of springboard
- addi r2, r2, _instruction_start-springboard // base address
- add r0, r0, r2 // calculate entry relative
- addi r2, r2, 0x4000 //TOC+0x8000 part 1
- addi r2, r2, (__toc_start+0x4000)@l //TOC+0x8000 part 2
- mtctr r0
- bctr // jump
+ mfspr r2, CFAR ;// get address of springboard
+ addi r2, r2, _SHA512_Init-springboard ;// base address
+ add r0, r0, r2 ;// calculate entry relative
+ addi r2, r2, 0x4000 ;//TOC+0x8000 part 1
+ addi r2, r2, (__toc_start+0x4000)@l ;//TOC+0x8000 part 2
+ mtctr r0
+ bctr ;// jump
# could put other assembly ocde routines here to conserver ROM space
# including the sreset routine
-# need to align on bootrombase+0x100 !!!
- .org .branchtable+0x100
- .globl _rom_sreset
+# need to align on securerombase+0x100 !!!
+ .org .branchtable+0x100
+ .globl _rom_sreset
_rom_sreset:
- li r0, rom_sreset@l
- b springboard
- nop
+ li r0, rom_sreset@l
+ b springboard
+ nop
+
+.section .data
+
+.global hbi_ImageId
+hbi_ImageId:
+ .space 128
diff --git a/src/securerom/ecverify.C b/src/securerom/ecverify.C
index 659d7d6fb..a4ba85a65 100644
--- a/src/securerom/ecverify.C
+++ b/src/securerom/ecverify.C
@@ -22,14 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/*----------------------------------------------------------------------
- * (C) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 2010
- * ALL RIGHTS RESERVED
- * IBM Research, Zurich and IBM Crypto Competency Center, Copenhagen
- *----------------------------------------------------------------------
- * Author: Tamas Visegrady (tvi@zurich.ibm.com)
- * Change: W Eric Hall (wehall@us.ibm.com)
- *----------------------------------------------------------------------*/
/** ECDSA verification on fixed curve/s (currently, on NIST P-521)
* The code below works for a compile-time constant curve, and requires
@@ -48,25 +40,23 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h> /* uint_fast8_t, uintN_t */
-#include <inttypes.h> /* PRIx64 used to format bn_t's */
+#include "inttypes.H" /* PRIx64 used to format bn_t's */
/**
* Define __LITTLE_ENDIAN or __BIG_ENDIAN for target.
*/
#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
- #define __BIG_ENDIAN
- #undef __LITTLE_ENDIAN
+ #define __BIG_ENDIAN
+ #undef __LITTLE_ENDIAN
#else
- #undef __BIG_ENDIAN
- #define __LITTLE_ENDIAN
+ #undef __BIG_ENDIAN
+ #define __LITTLE_ENDIAN
#endif
-#include "ecverify.h"
-
+#include <securerom/ecverify.H>
#define EC_PRIMEBITS 521 /* P521 */
-//#define EC_DEBUG 1 /* needs libc (not in Prism version) */
#define EC_STACKTRACE 1 /* debug only; currently, glibc */
#define NO_EC_DOUBLE_XY 1 /* do not implement ec_double_xy */
@@ -76,20 +66,6 @@ typedef uint_fast8_t bnindex_t;
#define BN_FMT "%016" PRIx64 /* PRIx64 from inttypes.h */
-
-// show word boundaries in bignumbers (diagnostics dump only)
-// #define EC_DEBUG_WORDS 1
-
-
-// define this if we construct ec_prime[] on the fly
-// saves code, adds runtime static structs; check your compiler if useful
-// does not make sense if non-exec, read-only constants are cheap
-//
-// #define BN_PRIME_GENERATED 1
-
-
-//--- nothing user-servicable below ---------------------------------------
-
#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
#error "Please define target endianness (__LITTLE_ENDIAN or __BIG_ENDIAN)"
#endif
@@ -106,8 +82,7 @@ typedef uint_fast8_t bnindex_t;
#define BN_MAXBIT (((bn_t) 1) << (BN_BITS -1))
-#define BITS2BN(bits) \
- (((bits) +BN_BITS -1) / BN_BITS)
+#define BITS2BN(bits) (((bits) +BN_BITS -1) / BN_BITS)
// we only deal with big numbers of fixed size
#define NWORDS BITS2BN( EC_PRIMEBITS )
@@ -123,21 +98,22 @@ typedef uint_fast8_t bnindex_t;
#else
static void __attribute__((noinline)) BN_COPY (bn_t *dst, const bn_t *src)
{
- size_t i;
- for(i=0;i<NWORDS;i++) {
- *dst++ = *src++;
- }
+ size_t i;
+ for(i=0;i<NWORDS;i++)
+ {
+ *dst++ = *src++;
+ }
}
#endif
#ifdef BN_POWER64_DBG
static void __attribute__((noinline)) BN_DUMP (int i, bn_t *top)
{
- asm volatile ("nop" : : "r" (i), "r" (top));
+ asm volatile ("nop" : : "r" (i), "r" (top));
}
static void BN_EXIT (void)
{
- asm volatile("b .Check_Stop");
+ asm volatile("b .Check_Stop");
}
#else
#define BN_DUMP(_i,_bn) ((void)0)
@@ -161,19 +137,15 @@ static void bn_dprint (const char *msg, const bn_t *m) ;
#define EC_DEVASSERT(cond) ((void) 0) // removed '((void) cond)' which still did the cond test
#endif
-
-
static bn_t bn_sub (bn_t *a, const bn_t *b) ;
static void bn_add (bn_t *a, const bn_t *b) ;
static void bn_mul (bn_t *r, const bn_t *a, const bn_t *b) ;
static void bn_modadd (bn_t *a, const bn_t *b) ;
static void bn_modsub (bn_t *a, const bn_t *b) ;
-// static int bn_cmp (const bn_t *a, const bn_t *b) ;
static int bn_cmp (const bn_t a[NWORDS], const bn_t b[NWORDS]) ;
// P521: a==-3, fixed curve parameter
-//
static int ec_double (bn_t *x, bn_t *y, bn_t *z) ;
@@ -189,105 +161,101 @@ static int ec_double (bn_t *x, bn_t *y, bn_t *z) ;
typedef struct {
- bn_t ec_prime[ NWORDS ];
+ bn_t ec_prime[ NWORDS ];
bn_t ec_order[ NWORDS ];
bn_t prime_px[ NWORDS ];
bn_t prime_py[ NWORDS ];
bn_t ec_order_qn[ NWORDS ];
} consts_t;
-const consts_t consts = {
+extern "C"
+const consts_t consts = {
//const bn_t ec_prime[ NWORDS ] =
- {
- BN_PRIME_MSW,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- },
-
-//-------------------------------------
+ {
+ BN_PRIME_MSW,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ },
//const bn_t ec_order[ NWORDS ] =
{
- 0x00000000000001ffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xffffffffffffffffLL,
- 0xfffffffffffffffaLL,
- 0x51868783bf2f966bLL,
- 0x7fcc0148f709a5d0LL,
- 0x3bb5c9b8899c47aeLL,
- 0xbb6fb71e91386409LL,
+ 0x00000000000001ffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xffffffffffffffffLL,
+ 0xfffffffffffffffaLL,
+ 0x51868783bf2f966bLL,
+ 0x7fcc0148f709a5d0LL,
+ 0x3bb5c9b8899c47aeLL,
+ 0xbb6fb71e91386409LL,
},
//const bn_t prime_px[ NWORDS ] = {
{
- 0x00000000000000c6LL,
- 0x858e06b70404e9cdLL,
- 0x9e3ecb662395b442LL,
- 0x9c648139053fb521LL,
- 0xf828af606b4d3dbaLL,
- 0xa14b5e77efe75928LL,
- 0xfe1dc127a2ffa8deLL,
- 0x3348b3c1856a429bLL,
- 0xf97e7e31c2e5bd66LL,
+ 0x00000000000000c6LL,
+ 0x858e06b70404e9cdLL,
+ 0x9e3ecb662395b442LL,
+ 0x9c648139053fb521LL,
+ 0xf828af606b4d3dbaLL,
+ 0xa14b5e77efe75928LL,
+ 0xfe1dc127a2ffa8deLL,
+ 0x3348b3c1856a429bLL,
+ 0xf97e7e31c2e5bd66LL,
},
//const bn_t prime_py[ NWORDS ] = {
{
- 0x0000000000000118LL,
- 0x39296a789a3bc004LL,
- 0x5c8a5fb42c7d1bd9LL,
- 0x98f54449579b4468LL,
- 0x17afbd17273e662cLL,
- 0x97ee72995ef42640LL,
- 0xc550b9013fad0761LL,
- 0x353c7086a272c240LL,
- 0x88be94769fd16650LL,
- },
-
- //-------------------------- mod mul by order (n) -------
- // MS 521 bits of Q/N, fractional part
- //
-// static const bn_t ec_order_qn[ NWORDS ] =
- {
- 0LL,
- 0LL,
- 0LL,
- 0LL,
- 0x0000000000000005LL,
- 0xae79787c40d06994LL,
- 0x8033feb708f65a2fLL,
- 0xc44a36477663b851LL,
- 0x449048e16ec79bf6LL,
- }
+ 0x0000000000000118LL,
+ 0x39296a789a3bc004LL,
+ 0x5c8a5fb42c7d1bd9LL,
+ 0x98f54449579b4468LL,
+ 0x17afbd17273e662cLL,
+ 0x97ee72995ef42640LL,
+ 0xc550b9013fad0761LL,
+ 0x353c7086a272c240LL,
+ 0x88be94769fd16650LL,
+ },
+
+//-------------------------- mod mul by order (n) -------
+// MS 521 bits of Q/N, fractional part
+//
+// static const bn_t ec_order_qn[ NWORDS ] =
+ {
+ 0LL,
+ 0LL,
+ 0LL,
+ 0LL,
+ 0x0000000000000005LL,
+ 0xae79787c40d06994LL,
+ 0x8033feb708f65a2fLL,
+ 0xc44a36477663b851LL,
+ 0x449048e16ec79bf6LL,
+ }
} ;
-inline const consts_t* __attribute__((pure)) consts_p() {
+inline const consts_t* __attribute__((pure)) consts_p()
+{
+
#ifdef EMULATE_HW
- return &consts;
+ return &consts;
#else
consts_t* result_consts_p;
- asm("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
- "sub %0,r2,%0 \n\t" // because subi does not work
- "addi %0,%0,(consts-0x8000)@l" : "=r" (result_consts_p) );
+ asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
+ "sub %0,2,%0 \n\t" // because subi does not work
+ "addi %0,%0,(consts-0x8000)@l" : "=r" (result_consts_p) );
return result_consts_p;
#endif
}
-//-------------------------------------
-
-
#define bn_ge_prime(val) (bn_cmp((val), consts_p()->ec_prime) >= 0)
#define bn_ge_order(val) (bn_cmp((val), consts_p()->ec_order) >= 0)
-
-//-------------------------------------
// P521: MSW has unused bits
#define BN_MSW_UNUSED_BITS (BN_BITS - BN_PRIME_MSW_BITS)
#define BN_MSW_UNUSED_BYTES ((BN_MSW_UNUSED_BITS +7) >>3)
@@ -300,23 +268,23 @@ inline const consts_t* __attribute__((pure)) consts_p() {
//
static bn_t bn_shl (bn_t *a, bn_t acc)
{
- bnindex_t i = NWORDS;
- bn_t cf = 0;
-
- EC_ASSERT(NULL != a);
- EC_ASSERT(0 == a[0]);
+ bnindex_t i = NWORDS;
+ bn_t cf = 0;
- a += NWORDS;
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(0 == a[0]);
- while (0<i--) {
- cf = *(--a);
- *a <<= BN_MSW_UNUSED_BITS;
- *a |= BN_MSW_UNUSED_MASK & (acc >> BN_PRIME_MSW_BITS);
+ a += NWORDS;
- acc = cf;
- }
+ while (0<i--)
+ {
+ cf = *(--a);
+ *a <<= BN_MSW_UNUSED_BITS;
+ *a |= BN_MSW_UNUSED_MASK & (acc >> BN_PRIME_MSW_BITS);
+ acc = cf;
+ }
- return cf;
+ return cf;
}
@@ -325,38 +293,40 @@ static bn_t bn_shl (bn_t *a, bn_t acc)
static void bn_printn (const char *msg, const bn_t *m, bnindex_t i)
{
- EC_ASSERT(NULL != m);
+ EC_ASSERT(NULL != m);
- if (NULL != msg)
- printf("%s", msg);
+ if (NULL != msg)
+ {
+ printf("%s", msg);
+ }
- while (0 < i--) {
+ while (0 < i--)
+ {
#if defined(EC_DEBUG_WORDS)
- if (i<NWORDS-1)
- printf(".");
+ if (i<NWORDS-1)
+ {
+ printf(".");
+ }
#endif
- printf(BN_FMT, *(m++));
- }
+ printf(BN_FMT, *(m++));
+ }
- printf("\n");
+ printf("\n");
}
-
static void bn_print (const char *msg, const bn_t *m)
{
- bn_printn(msg, m, NWORDS);
+ bn_printn(msg, m, NWORDS);
}
-
static void bn_dprint (const char *msg, const bn_t *m)
{
- bn_printn(msg, m, NWORDS+NWORDS);
+ bn_printn(msg, m, NWORDS+NWORDS);
}
#endif /* defined(EC_DEBUG) */
-
//============================================== modular multiplication ====
// this section should be routed to hardware, when it becomes available
@@ -368,11 +338,12 @@ static void bn_dprint (const char *msg, const bn_t *m)
#define bn_dclear(n) bn_clr((n), 2*NWORDS)
static void __attribute__((noinline)) bn_clr (bn_t *dst, size_t s)
{
- size_t i;
- dst--;
- for(i=0;i<s;i++) {
- *(++dst) = 0LL;
- }
+ size_t i;
+ dst--;
+ for(i=0;i<s;i++)
+ {
+ *(++dst) = 0LL;
+ }
}
#endif
@@ -384,40 +355,41 @@ static void __attribute__((noinline)) bn_clr (bn_t *dst, size_t s)
static bn_t bn_dmul (bn_t a, bn_t b)
{
#ifdef EC_POWER64_ASM
- bn_t t;
- asm("mulhdu %0,%1,%2" : "=r" (t) : "r" (a), "r" (b) );
- return t;
+ bn_t t;
+ asm("mulhdu %0,%1,%2" : "=r" (t) : "r" (a), "r" (b) );
+ return t;
#else
- hbn_t ah, al, bh, bl;
- bn_t t;
-
- al = a;
- ah = (hbn_t) (a >> HBN_BITS);
- bl = b;
- bh = (hbn_t) (b >> HBN_BITS);
-
- a = ((bn_t) ah) * bh; // collects high word
- b = ((bn_t) al) * bl; // collects low word
-
- t = ((bn_t) ah) * bl;
- a += t >> HBN_BITS;
- t <<= HBN_BITS;
- if (b+t < t)
- ++a;
- b += t;
-
- t = ((bn_t) al) * bh;
- a += t >> HBN_BITS;
- t <<= HBN_BITS;
- if (b+t < t)
- ++a;
-// b += t; // we don't actually need this, only its carry above
- return a;
+ hbn_t ah, al, bh, bl;
+ bn_t t;
+
+ al = a;
+ ah = (hbn_t) (a >> HBN_BITS);
+ bl = b;
+ bh = (hbn_t) (b >> HBN_BITS);
+
+ a = ((bn_t) ah) * bh; // collects high word
+ b = ((bn_t) al) * bl; // collects low word
+
+ t = ((bn_t) ah) * bl;
+ a += t >> HBN_BITS;
+ t <<= HBN_BITS;
+ if (b+t < t)
+ {
+ ++a;
+ }
+ b += t;
+
+ t = ((bn_t) al) * bh;
+ a += t >> HBN_BITS;
+ t <<= HBN_BITS;
+ if (b+t < t)
+ {
+ ++a;
+ }
+ return a;
#endif
}
-
-//-------------------------------------
/** multiply (a,NWORDS) by (b,NWORDS) into (r,2*NWORDS)
* we collect 2-word multiples, and carries across columns in two
* arrays:
@@ -435,110 +407,121 @@ static bn_t bn_dmul (bn_t a, bn_t b)
//
static void bn_mul (bn_t *r, const bn_t *a, const bn_t *b)
{
- unsigned char cf[ NWORDS+NWORDS ]; /* carry collector */
- bnindex_t i, j;
- bn_t ph, pl; /* product high,low words */
+ unsigned char cf[ NWORDS+NWORDS ]; /* carry collector */
+ bnindex_t i, j;
+ bn_t ph, pl; /* product high,low words */
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- bn_dclear(r);
- memset(cf, 0, sizeof(cf));
+ bn_dclear(r);
+ memset(cf, 0, sizeof(cf));
- for (j=0; j<NWORDS; ++j) {
- for (i=0; i<NWORDS; ++i) {
- ph = bn_dmul(a[i], b[j]);
- pl = a[i] * b[j];
+ for (j=0; j<NWORDS; ++j)
+ {
+ for (i=0; i<NWORDS; ++i)
+ {
+ ph = bn_dmul(a[i], b[j]);
+ pl = a[i] * b[j];
#ifdef EC_POWER64_ASM
- asm("addc %0,%2,%4\n"
- "addze %1,%3"
- : "=r" (r[i+j]), "=r" (cf[i+j])
- : "0" (r[i+j]), "1" (cf[i+j]), "r" (ph)
- );
- asm("addc %0,%2,%4\n"
- "addze %1,%3"
- : "=r" (r[i+j+1]), "=r" (cf[i+j+1])
- : "0" (r[i+j+1]), "1" (cf[i+j+1]), "r" (pl)
- );
+ asm("addc %0,%2,%4\n"
+ "addze %1,%3"
+ : "=r" (r[i+j]), "=r" (cf[i+j])
+ : "0" (r[i+j]), "1" (cf[i+j]), "r" (ph)
+ );
+ asm("addc %0,%2,%4\n"
+ "addze %1,%3"
+ : "=r" (r[i+j+1]), "=r" (cf[i+j+1])
+ : "0" (r[i+j+1]), "1" (cf[i+j+1]), "r" (pl)
+ );
#else
- r[i+j] += ph;
- if (r[i+j] < ph) {
- EC_ASSERT(i+j>0); // MSW can't carry to left
- (cf[i+j-1])++;
- }
-
- r[i+j+1] += pl;
- if (r[i+j+1] < pl)
- (cf[i+j])++;
+ r[i+j] += ph;
+ if (r[i+j] < ph)
+ {
+ EC_ASSERT(i+j>0); // MSW can't carry to left
+ (cf[i+j-1])++;
+ }
+
+ r[i+j+1] += pl;
+ if (r[i+j+1] < pl)
+ {
+ (cf[i+j])++;
+ }
#endif
- }
- }
+ }
+ }
- // propagate carries (LS to MS)
+ // propagate carries (LS to MS)
#ifdef EC_POWER64_ASM
- i=NWORDS+NWORDS-2;
- asm("addc %0,%1,%2"
- : "=r" (r[i])
- : "0" (r[i]), "r" (cf[i+1])
- );
- for ( ; 0<i; ) {
- --i;
- asm("adde %0,%1,%2"
- : "=r" (r[i])
- : "0" (r[i]), "r" (cf[i+1])
- );
+ i=NWORDS+NWORDS-2;
+ asm("addc %0,%1,%2"
+ : "=r" (r[i])
+ : "0" (r[i]), "r" (cf[i+1])
+ );
+ for ( ; 0<i; )
+ {
+ --i;
+ asm("adde %0,%1,%2"
+ : "=r" (r[i])
+ : "0" (r[i]), "r" (cf[i+1])
+ );
#else
- for (i=NWORDS+NWORDS; 0<i; ) {
- if (cf[--i]) {
- r[i] += cf[i];
- if (r[i] < cf[i]) {
- EC_ASSERT(0 < i);
- cf[i-1]++;
- }
- }
+ for (i=NWORDS+NWORDS; 0<i; )
+ {
+ if (cf[--i])
+ {
+ r[i] += cf[i];
+ if (r[i] < cf[i])
+ {
+ EC_ASSERT(0 < i);
+ cf[i-1]++;
+ }
+ }
#endif
- }
+ }
}
#else
static void bn_mul (bn_t *r, const bn_t *a, const bn_t *b)
{
- bnindex_t i, j;
- bn_t ph, pl, th, tb; /* product high,low words */
+ bnindex_t i, j;
+ bn_t ph, pl, th, tb; /* product high,low words */
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- bn_dclear(r);
+ bn_dclear(r);
- r += NWORDS;
- b += NWORDS;
- for (j=0; j<NWORDS; j++) {
- th = 0LL;
- tb = *(--b);
r += NWORDS;
- a += NWORDS;
- for (i=0; i<NWORDS; i++) {
- asm("mulld %0,%1,%2" //pl = *(--a) * tb
- : "=r" (pl)
- : "r" (*(--a)), "r" (tb)
- );
- asm("mulhdu %0,%1,%2" //ph = *a * tb
- : "=r" (ph)
- : "r" (*a), "r" (tb)
- );
- asm("addc %1,%5,%4\n" //pl += *(--r)
- "addze %2,%6\n" //ph += ca
- "addc %0,%5,%7\n" //*r = pl + th
- "addze %3,%6" //th = ph + ca
- : "=r" (*r), "=r" (pl), "=r" (ph), "=r" (th)
- : "0" (*(--r)), "1" (pl), "2" (ph), "3" (th)
- );
+ b += NWORDS;
+ for (j=0; j<NWORDS; j++)
+ {
+ th = 0LL;
+ tb = *(--b);
+ r += NWORDS;
+ a += NWORDS;
+ for (i=0; i<NWORDS; i++)
+ {
+ asm("mulld %0,%1,%2" //pl = *(--a) * tb
+ : "=r" (pl)
+ : "r" (*(--a)), "r" (tb)
+ );
+ asm("mulhdu %0,%1,%2" //ph = *a * tb
+ : "=r" (ph)
+ : "r" (*a), "r" (tb)
+ );
+ asm("addc %1,%5,%4\n" //pl += *(--r)
+ "addze %2,%6\n" //ph += ca
+ "addc %0,%5,%7\n" //*r = pl + th
+ "addze %3,%6" //th = ph + ca
+ : "=r" (*r), "=r" (pl), "=r" (ph), "=r" (th)
+ : "0" (*(--r)), "1" (pl), "2" (ph), "3" (th)
+ );
+ }
+ *(--r) = th;
}
- *(--r) = th;
- }
}
#endif
@@ -546,75 +529,77 @@ static void bn_mul (bn_t *r, const bn_t *a, const bn_t *b)
#ifdef BN_POWER64_SQR
static void bn_sqr (bn_t *r, const bn_t *a)
{
- bnindex_t i, j;
- const bn_t *b; /* product high,low words */
- bn_t *c, ph, pl, ta, t0, t1, t2; /* product high,low words */
+ bnindex_t i, j;
+ const bn_t *b; /* product high,low words */
+ bn_t *c, ph, pl, ta, t0, t1, t2; /* product high,low words */
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != a);
- bn_dclear(r);
+ bn_dclear(r);
- r += 2*NWORDS;
- a += NWORDS;
- for (j=0; j<NWORDS-1; j++) {
+ r += 2*NWORDS;
+ a += NWORDS;
+ for (j=0; j<NWORDS-1; j++)
+ {
+ ta = *(--a);
+ c = r;
+ b = a;
+ asm("mulld %0,%2,%2\n" //pl = ta * ta
+ "mulhdu %1,%2,%2" //ph = ta * ta
+ : "=r" (pl), "=r" (ph)
+ : "r" (ta)
+ );
+ asm("addc %0,%2,%4\n" //*r = *(--r) + pl
+ "addze %1,%3" //t0 = ph + ca
+ : "=r" (*c), "=r" (t0)
+ : "0" (*(--c)), "r" (ph), "r" (pl)
+ );
+ t1 = 0L;
+ for (i=j+1; i<NWORDS; i++)
+ {
+ t2 = 0L;
+ asm("mulld %0,%1,%2" //pl = *(--b) * ta
+ : "=r" (pl)
+ : "r" (*(--b)), "r" (ta)
+ );
+ asm("mulhdu %0,%1,%2" //ph = *b * ta
+ : "=r" (ph)
+ : "r" (*b), "r" (ta)
+ );
+ asm("addc %1,%7,%7\n" //pl += pl
+ "adde %2,%8,%8\n" //ph += ph + ca
+ "addze %5,%11\n" //t2 += ca
+ "addc %1,%7,%9\n" //pl += t0
+ "adde %2,%8,%10\n" //ph += t1 + ca
+ "addze %5,%11\n" //t2 += ca
+ "addc %0,%6,%7\n" //*r = *(--r) + pl
+ "addze %3,%8\n" //t0 = ph + ca
+ "addze %4,%11" //t1 = t2 + ca
+ : "=r" (*c), "=r" (pl), "=r" (ph), "=r" (t0), "=r" (t1), "=r" (t2)
+ : "0" (*(--c)), "1" (pl), "2" (ph), "3" (t0), "4" (t1), "5" (t2)
+ );
+ }
+ asm("addc %0,%2,%4\n" //*r = *(--r) + t0
+ "addze %1,%3" //t1 += ca
+ : "=r" (*c), "=r" (t1)
+ : "0" (*(--c)), "1" (t1), "r" (t0)
+ );
+ *(--c) = t1;
+ r -= 2;
+ }
ta = *(--a);
- c = r;
- b = a;
- asm("mulld %0,%2,%2\n" //pl = ta * ta
- "mulhdu %1,%2,%2" //ph = ta * ta
+ asm("mulld %0,%2,%2\n" //pl = ta * ta
+ "mulhdu %1,%2,%2" //ph = ta * ta
: "=r" (pl), "=r" (ph)
: "r" (ta)
);
- asm("addc %0,%2,%4\n" //*r = *(--r) + pl
- "addze %1,%3" //t0 = ph + ca
- : "=r" (*c), "=r" (t0)
- : "0" (*(--c)), "r" (ph), "r" (pl)
+ asm("addc %0,%2,%4\n" //*r = *(--r) + pl
+ "addze %1,%3" //ph += ca
+ : "=r" (*r), "=r" (ph)
+ : "0" (*(--r)), "1" (ph), "r" (pl)
);
- t1 = 0L;
- for (i=j+1; i<NWORDS; i++) {
- t2 = 0L;
- asm("mulld %0,%1,%2" //pl = *(--b) * ta
- : "=r" (pl)
- : "r" (*(--b)), "r" (ta)
- );
- asm("mulhdu %0,%1,%2" //ph = *b * ta
- : "=r" (ph)
- : "r" (*b), "r" (ta)
- );
- asm("addc %1,%7,%7\n" //pl += pl
- "adde %2,%8,%8\n" //ph += ph + ca
- "addze %5,%11\n" //t2 += ca
- "addc %1,%7,%9\n" //pl += t0
- "adde %2,%8,%10\n" //ph += t1 + ca
- "addze %5,%11\n" //t2 += ca
- "addc %0,%6,%7\n" //*r = *(--r) + pl
- "addze %3,%8\n" //t0 = ph + ca
- "addze %4,%11" //t1 = t2 + ca
- : "=r" (*c), "=r" (pl), "=r" (ph), "=r" (t0), "=r" (t1), "=r" (t2)
- : "0" (*(--c)), "1" (pl), "2" (ph), "3" (t0), "4" (t1), "5" (t2)
- );
- }
- asm("addc %0,%2,%4\n" //*r = *(--r) + t0
- "addze %1,%3" //t1 += ca
- : "=r" (*c), "=r" (t1)
- : "0" (*(--c)), "1" (t1), "r" (t0)
- );
- *(--c) = t1;
- r -= 2;
- }
- ta = *(--a);
- asm("mulld %0,%2,%2\n" //pl = ta * ta
- "mulhdu %1,%2,%2" //ph = ta * ta
- : "=r" (pl), "=r" (ph)
- : "r" (ta)
- );
- asm("addc %0,%2,%4\n" //*r = *(--r) + pl
- "addze %1,%3" //ph += ca
- : "=r" (*r), "=r" (ph)
- : "0" (*(--r)), "1" (ph), "r" (pl)
- );
- *(--r) += ph;
+ *(--r) += ph;
}
#endif
#endif
@@ -636,34 +621,40 @@ static void bn_sqr (bn_t *r, const bn_t *a)
#ifndef EC_POWER64_RED
static void bn_modred_p521 (bn_t *r, bn_t *a)
{
- bn_t *al;
-bn_t *rc = r;
+ bn_t *al;
+ bn_t *rc = r;
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != a);
- EC_ASSERT((const bn_t *) r != a);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT((const bn_t *) r != a);
- al = a+NWORDS;
+ al = a+NWORDS;
- // P521: product is 1042 bits, MSW of double-width bignum always 0
- //
- EC_ASSERT(0 == a[0]);
+ // P521: product is 1042 bits, MSW of double-width bignum always 0
+ //
+ EC_ASSERT(0 == a[0]);
- BN_COPY(rc, a);
- bn_shl(rc, *al);
+ BN_COPY(rc, a);
+ bn_shl(rc, *al);
- *al &= BN_PRIME_MSW_MASK;
+ *al &= BN_PRIME_MSW_MASK;
- if (bn_cmp(rc, consts_p()->ec_prime) >= 0)
- bn_sub(rc, consts_p()->ec_prime); // XXX can this happen? (mod-based input)
+ if (bn_cmp(rc, consts_p()->ec_prime) >= 0)
+ {
+ bn_sub(rc, consts_p()->ec_prime); // XXX can this happen? (mod-based input)
+ }
- if (bn_cmp(al, consts_p()->ec_prime) >= 0)
- bn_sub(al, consts_p()->ec_prime);
- EC_ASSERT(!bn_ge_prime(al)); // al must have bitlen <= ec_prime
+ if (bn_cmp(al, consts_p()->ec_prime) >= 0)
+ bn_sub(al, consts_p()->ec_prime);
+ {
+ EC_ASSERT(!bn_ge_prime(al)); // al must have bitlen <= ec_prime
+ }
- bn_add(rc, al);
- if (bn_cmp(rc, consts_p()->ec_prime) >= 0)
- bn_sub(rc, consts_p()->ec_prime);
+ bn_add(rc, al);
+ if (bn_cmp(rc, consts_p()->ec_prime) >= 0)
+ {
+ bn_sub(rc, consts_p()->ec_prime);
+ }
}
#else
#ifdef BN_POWER64_SQR
@@ -672,71 +663,74 @@ static void __attribute__((noinline)) bn_modred_fast (bn_t *r, bn_t *a)
static void bn_modred_fast (bn_t *r, bn_t *a)
#endif
{
- bn_t *ah = a + NWORDS;
- bn_t *al = a + 2*NWORDS;
- bn_t t0 = (*(a+1) >> 18) + (*ah >> 9);
- bn_t t1, t2, t3=0;
- size_t i;
- r += NWORDS;
- for (i=0; i<NWORDS-2; i++) {
+ bn_t *ah = a + NWORDS;
+ bn_t *al = a + 2*NWORDS;
+ bn_t t0 = (*(a+1) >> 18) + (*ah >> 9);
+ bn_t t1, t2, t3=0;
+ size_t i;
+ r += NWORDS;
+ for (i=0; i<NWORDS-2; i++) {
+ t1 = *(--ah) << 55;
+ t2 = *ah >> 9;
+ asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
+ "addze %2,%6\n" //t2 += ca;
+ "addc %0,%4,%8\n" //*(--r) = t3 + t1;
+ "addze %1,%6" //t0 = t2 + ca;
+ : "=r" (*(--r)), "=r" (t0), "=r" (t2), "=r" (t3)
+ : "3" (t3), "1" (t0), "2" (t2), "r" (*(--al)), "r" (t1)
+ );
+ }
t1 = *(--ah) << 55;
- t2 = *ah >> 9;
- asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
- "addze %2,%6\n" //t2 += ca;
- "addc %0,%4,%8\n" //*(--r) = t3 + t1;
- "addze %1,%6" //t0 = t2 + ca;
+ t2 = (*ah >> 9)&BN_PRIME_MSW_MASK;
+ asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
+ "addze %2,%6\n" //t2 += ca;
+ "addc %0,%4,%8\n" //*(--r) = t3 + t1;
+ "addze %1,%6" //t0 = t2 + ca;
: "=r" (*(--r)), "=r" (t0), "=r" (t2), "=r" (t3)
: "3" (t3), "1" (t0), "2" (t2), "r" (*(--al)), "r" (t1)
);
- }
- t1 = *(--ah) << 55;
- t2 = (*ah >> 9)&BN_PRIME_MSW_MASK;
- asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
- "addze %2,%6\n" //t2 += ca;
- "addc %0,%4,%8\n" //*(--r) = t3 + t1;
- "addze %1,%6" //t0 = t2 + ca;
- : "=r" (*(--r)), "=r" (t0), "=r" (t2), "=r" (t3)
- : "3" (t3), "1" (t0), "2" (t2), "r" (*(--al)), "r" (t1)
- );
- *(--r) = (*(--al)&BN_PRIME_MSW_MASK) + t0;
+ *(--r) = (*(--al)&BN_PRIME_MSW_MASK) + t0;
}
static void __attribute__((noinline)) bn_modred_slow (bn_t *r)
{
- size_t i;
- if (*r > BN_PRIME_MSW_MASK) {
- bn_t t0 = *r >> 9;
- *r &= BN_PRIME_MSW_MASK;
- r += NWORDS;
- asm("addc %0,%1,%2"
- : "=r" (*r)
- : "0" (*(--r)), "r" (t0)
- );
- for (i=0; i<NWORDS-1; i++) {
- asm("addze %0,%1"
- : "=r" (*r)
- : "0" (*(--r))
- );
+ size_t i;
+ if (*r > BN_PRIME_MSW_MASK)
+ {
+ bn_t t0 = *r >> 9;
+ *r &= BN_PRIME_MSW_MASK;
+ r += NWORDS;
+ asm("addc %0,%1,%2"
+ : "=r" (*r)
+ : "0" (*(--r)), "r" (t0)
+ );
+ for (i=0; i<NWORDS-1; i++)
+ {
+ asm("addze %0,%1"
+ : "=r" (*r)
+ : "0" (*(--r))
+ );
+ }
+ }
+ if (bn_ge_prime(r))
+ {
+ bn_sub(r, consts_p()->ec_prime);
}
- }
- if (bn_ge_prime(r))
- bn_sub(r, consts_p()->ec_prime);
}
#endif
-
static void bn_modmul_prime (bn_t *a, const bn_t *b)
{
- bn_t prod[ NWORDS+NWORDS ];
+ bn_t prod[ NWORDS+NWORDS ];
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- bn_mul(prod, a, b);
+ bn_mul(prod, a, b);
#ifdef EC_POWER64_RED
- bn_modred_fast(a, prod); // accepts upto 46 extra bits => outputs at most 1 extra bit (522)
+ bn_modred_fast(a, prod); // accepts upto 46 extra bits => outputs at most 1 extra bit (522)
#else
- bn_modred_p521(a, prod);
+ bn_modred_p521(a, prod);
#endif
}
@@ -744,24 +738,22 @@ static void bn_modmul_prime (bn_t *a, const bn_t *b)
static void bn_modsqr_prime (bn_t *a)
{
#ifdef BN_POWER64_SQR
- bn_t prod[ NWORDS+NWORDS ];
+ bn_t prod[ NWORDS+NWORDS ];
- EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != a);
- bn_sqr(prod, a);
+ bn_sqr(prod, a);
#ifdef EC_POWER64_RED
- bn_modred_fast(a, prod); // accepts upto 46 extra bits => outputs at most 1 extra bit (522)
+ bn_modred_fast(a, prod); // accepts upto 46 extra bits => outputs at most 1 extra bit (522)
#else
- bn_modred_p521(a, prod);
+ bn_modred_p521(a, prod);
#endif
#else
- bn_modmul_prime(a, a);
+ bn_modmul_prime(a, a);
#endif
}
#endif
-
-
// mod reduce 2*NWORDS to NWORDS through approximate division
//
// input (a,2*NWORDS) <= N^2 -2*N +1
@@ -780,88 +772,91 @@ static void bn_modsqr_prime (bn_t *a)
//
static void bn_modred_p521_order (bn_t *r, const bn_t *a)
{
- bn_t dbl[ NWORDS+NWORDS ];
+ bn_t dbl[ NWORDS+NWORDS ];
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != a);
- EC_ASSERT((const bn_t *) r != a);
-// XXX full overlap check
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT((const bn_t *) r != a);
+ // XXX full overlap check
- // P521: product is 1042 bits, MSW of double-width bignum always 0
- //
- EC_ASSERT(0 == a[0]);
+ // P521: product is 1042 bits, MSW of double-width bignum always 0
+ //
+ EC_ASSERT(0 == a[0]);
- BN_COPY(r, a);
- bn_shl(r, a[NWORDS]);
+ BN_COPY(r, a);
+ bn_shl(r, a[NWORDS]);
- bn_mul(dbl, r, consts_p()->ec_order_qn);
- bn_shl(dbl, dbl[NWORDS]); // MS 521 bits of product
- bn_add(r, dbl);
+ bn_mul(dbl, r, consts_p()->ec_order_qn);
+ bn_shl(dbl, dbl[NWORDS]); // MS 521 bits of product
+ bn_add(r, dbl);
- bn_mul(dbl, r, consts_p()->ec_order); // N * floor(A / N)
- EC_ASSERT(bn_cmp(dbl, a) <= 0);
- EC_ASSERT(bn_cmp(dbl+NWORDS, a+NWORDS) <= 0);
+ bn_mul(dbl, r, consts_p()->ec_order); // N * floor(A / N)
+ EC_ASSERT(bn_cmp(dbl, a) <= 0);
+ EC_ASSERT(bn_cmp(dbl+NWORDS, a+NWORDS) <= 0);
- BN_COPY(r, a+NWORDS);
- bn_sub(r, dbl+NWORDS); // A - (N * floor(A/N))
+ BN_COPY(r, a+NWORDS);
+ bn_sub(r, dbl+NWORDS); // A - (N * floor(A/N))
- if (bn_cmp(r, consts_p()->ec_order) >= 0)
- bn_sub(r, consts_p()->ec_order);
+ if (bn_cmp(r, consts_p()->ec_order) >= 0)
+ {
+ bn_sub(r, consts_p()->ec_order);
+ }
- if (bn_cmp(r, consts_p()->ec_order) >= 0)
- bn_sub(r, consts_p()->ec_order); // XXX can this still be 2+ over?
+ if (bn_cmp(r, consts_p()->ec_order) >= 0)
+ {
+ bn_sub(r, consts_p()->ec_order); // XXX can this still be 2+ over?
+ }
- EC_ASSERT(bn_cmp(r, consts_p()->ec_order) < 0);
+ EC_ASSERT(bn_cmp(r, consts_p()->ec_order) < 0);
}
static void bn_modmul_order (bn_t *a, const bn_t *b)
{
- bn_t prod[ NWORDS+NWORDS ];
+ bn_t prod[ NWORDS+NWORDS ];
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- bn_mul(prod, a, b);
- bn_modred_p521_order(a, prod);
+ bn_mul(prod, a, b);
+ bn_modred_p521_order(a, prod);
}
-//-------------------------------------
// negative,0,positive for a<b, a==b, a>b
//
#if defined(__BIG_ENDIAN) && !defined(BN_POWER64_CMP)
static int bn_cmp (const bn_t *a, const bn_t *b)
{
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- return memcmp(a, b, sizeof(bn_t)*NWORDS);
+ return memcmp(a, b, sizeof(bn_t)*NWORDS);
}
-#else /* defined(__BIG_ENDIAN) */
+#else /* defined(__BIG_ENDIAN) */
static int __attribute__((noinline)) bn_cmp (const bn_t *a, const bn_t *b)
{
- bnindex_t i;
+ bnindex_t i;
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- for (i=0; i<NWORDS; ++i) {
- if (a[i] != b[i])
- return 1 - ((a[i] < b[i]) <<1);
- }
+ for (i=0; i<NWORDS; ++i)
+ {
+ if (a[i] != b[i])
+ {
+ return 1 - ((a[i] < b[i]) <<1);
+ }
+ }
- return 0;
+ return 0;
}
#endif /* defined(__BIG_ENDIAN) */
-
-
-//-------------------------------------
//removed:
//static const bn_t bn_zero[ NWORDS ];
@@ -869,366 +864,368 @@ static int __attribute__((noinline)) bn_cmp (const bn_t *a, const bn_t *b)
//
static int bn_is_zero (const bn_t *m, unsigned int mn)
{
- EC_ASSERT(NULL != m);
- EC_ASSERT(mn < NWORDS);
+ EC_ASSERT(NULL != m);
+ EC_ASSERT(mn < NWORDS);
- const unsigned char *p2 = (const unsigned char *) m;
- size_t n=sizeof(bn_t)*(NWORDS-mn);
+ const unsigned char *p2 = (const unsigned char *) m;
+ size_t n=sizeof(bn_t)*(NWORDS-mn);
- while (n-- > 0) {
- if (0 != *p2)
- return !(0 - *p2);
- p2 += 1;
- }
-
- return !0;
+ while (n-- > 0)
+ {
+ if (0 != *p2)
+ {
+ return !(0 - *p2);
+ }
+ p2 += 1;
+ }
-// replaces:
-// return !memcmp(bn_zero, m, sizeof(bn_t)*(NWORDS-mn));
+ return !0;
}
-//-------------------------------------
static void __attribute__((noinline)) bn_add (bn_t *a, const bn_t *b)
{
- bn_t aw, cf = 0; /* aw: copy of current word to allow a==b */
- bnindex_t i = NWORDS;
+ bn_t aw, cf = 0; /* aw: copy of current word to allow a==b */
+ bnindex_t i = NWORDS;
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
- a += NWORDS-1;
- b += NWORDS-1;
+ a += NWORDS-1;
+ b += NWORDS-1;
- while (0 < i--) {
- aw = *a;
- if (cf)
- cf = (0 == ++aw);
-
- aw += *b;
- cf |= (aw < *(b--));
- *(a--) = aw;
- }
+ while (0 < i--)
+ {
+ aw = *a;
+ if (cf)
+ {
+ cf = (0 == ++aw);
+ }
+ aw += *b;
+ cf |= (aw < *(b--));
+ *(a--) = aw;
+ }
}
-//-------------------------------------
// a,b < prime
// never with order as base
//
static void bn_modadd (bn_t *a, const bn_t *b)
{
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
- //EC_ASSERT(!bn_ge_prime(a));
- //EC_ASSERT(!bn_ge_prime(b));
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
+ //EC_ASSERT(!bn_ge_prime(a));
+ //EC_ASSERT(!bn_ge_prime(b));
- bn_add(a, b); // P521: can not generate carry (unused MSW bits)
- // other curves need to handle this carry
+ bn_add(a, b); // P521: can not generate carry (unused MSW bits)
+ // other curves need to handle this carry
#ifndef EC_POWER64_RED
- if (bn_ge_prime(a))
- bn_sub(a, consts_p()->ec_prime);
+ if (bn_ge_prime(a))
+ {
+ bn_sub(a, consts_p()->ec_prime);
+ }
#endif
}
-//-------------------------------------
// never with order as base
static bn_t bn_sub (bn_t *a, const bn_t *b)
{
- bnindex_t i = NWORDS;
- bn_t bw, cf = 0;
-
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
-
- a += NWORDS-1;
- b += NWORDS-1;
-
- while (0 < i--) {
- if (cf)
- cf = (0 == (*a)--);
-
- bw = *b;
- cf |= (*a < *(b--));
- *(a--) -= bw;
- }
+ bnindex_t i = NWORDS;
+ bn_t bw, cf = 0;
+
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
+
+ a += NWORDS-1;
+ b += NWORDS-1;
+
+ while (0 < i--) {
+ if (cf)
+ {
+ cf = (0 == (*a)--);
+ }
+ bw = *b;
+ cf |= (*a < *(b--));
+ *(a--) -= bw;
+ }
- return cf;
+ return cf;
}
-
-//-------------------------------------
// never modular-subtracting with ec_order[], only with ec_prime[]
// therefore, implicit modulus
//
static void bn_modsub (bn_t *a, const bn_t *b)
{
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != b);
- //EC_ASSERT(!bn_ge_prime(a));
- EC_ASSERT(!bn_ge_prime(b));
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != b);
+ EC_ASSERT(!bn_ge_prime(b));
- if (bn_sub(a, b))
- bn_add(a, consts_p()->ec_prime);
+ if (bn_sub(a, b))
+ {
+ bn_add(a, consts_p()->ec_prime);
+ }
}
-
-
-//-------------------------------------
// only rn LS words are touched
//
static void bn_shl_n (bn_t r[NWORDS], unsigned int rn, unsigned int bits)
{
- bn_t cf = 0, cfin;
+ bn_t cf = 0, cfin;
- EC_DEVASSERT(NULL != r);
- EC_ASSERT(rn <= NWORDS);
+ EC_DEVASSERT(NULL != r);
+ EC_ASSERT(rn <= NWORDS);
- r += NWORDS-rn;
+ r += NWORDS-rn;
- if (bits >= BN_BITS) { // unlikely, most modinv shift is <5 bits
- cfin = bits / BN_BITS; // whole words
+ if (bits >= BN_BITS) // unlikely, most modinv shift is <5 bits
+ {
+ cfin = bits / BN_BITS; // whole words
- memmove(r, r+cfin, (NWORDS-cfin)*sizeof(bn_t));
+ memmove(r, r+cfin, (NWORDS-cfin)*sizeof(bn_t));
#ifndef BN_POWER64_CLR
- memset(r+NWORDS-cfin, 0, cfin*sizeof(bn_t));
+ memset(r+NWORDS-cfin, 0, cfin*sizeof(bn_t));
#else
- bn_clr(r+NWORDS-cfin, cfin);
+ bn_clr(r+NWORDS-cfin, cfin);
#endif
- bits %= BN_BITS;
- }
+ bits %= BN_BITS;
+ }
- if (bits) {
- r += rn-1;
+ if (bits)
+ {
+ r += rn-1;
+ while (0<rn--)
+ {
+ cfin = cf;
+ cf = (*r >> (BN_BITS - bits));
+ *r <<= bits;
+ *r |= cfin;
+ --r;
+ }
+ }
+}
- while (0<rn--) {
- cfin = cf;
- cf = (*r >> (BN_BITS - bits));
+static unsigned int bn_bits (const bn_t *a)
+{
+ unsigned int full = 8*BNBYTES;
+ bnindex_t i;
+ bn_t an;
- *r <<= bits;
- *r |= cfin;
- --r;
- }
- }
+ for (i=0; i<NWORDS; ++i)
+ {
+ full -= BN_BITS;
+ an = a[i];
+
+ if (!an)
+ {
+ continue;
+ }
+
+ while (an > 0xff)
+ {
+ full += 8;
+ an >>= 8;
+ }
+
+ while (an)
+ {
+ ++full;
+ an >>= 1;
+ }
+ return full;
+ }
+ return 0;
}
+// XXX route to bnt_msbit
+//
+#define bn_is_negative(p) (0x1000 & (*(p)))
-
-static unsigned int bn_bits (const bn_t *a)
+// inv stores S during run
+//
+static int bn_modinv(bn_t *inv, const bn_t *a, const bn_t *n)
{
- unsigned int full = 8*BNBYTES;
- bnindex_t i;
- bn_t an;
+ bn_t r[ NWORDS ], s[ NWORDS ], u[ NWORDS ], v[ NWORDS ],
+ ss[ NWORDS ], vs[ NWORDS ]; // shifted S,V
+ unsigned int shl, ub, vb; // shift amount; bitcount
+ bn_t *pr = r, *ps = s, *pu = u, *pv = v, *pt;
- for (i=0; i<NWORDS; ++i) {
- full -= BN_BITS;
- an = a[i];
+ EC_ASSERT(NULL != inv);
+ EC_ASSERT(NULL != a);
+ EC_ASSERT(NULL != n);
+ EC_ASSERT(bn_cmp(a,n) < 0);
+ EC_ASSERT(!bn_is_zero(a,0));
- if (!an)
- continue;
+ bn_clear(r);
+ bn_clear(s);
+ BN_LSW(s) = 1;
- while (an > 0xff) {
- full += 8;
- an >>= 8;
- }
+ BN_COPY(u, n);
+ BN_COPY(v, a);
- while (an) {
- ++full;
- an >>= 1;
- }
+ // ub = bn_bits(u);
+ ub = EC_PRIMEBITS; // P521: only ec_prime or ec_order possible
+ vb = bn_bits(v);
- return full;
- }
+ while (1 < vb)
+ {
+ EC_ASSERT(ub >= vb);
+ shl = ub-vb;
+
+ BN_COPY(vs, pv);
+ BN_COPY(ss, ps);
+ if (shl)
+ {
+ bn_shl_n(vs, NWORDS, shl);
+ bn_shl_n(ss, NWORDS, shl);
+ }
+
+ if (bn_is_negative(pv) == bn_is_negative(pu))
+ {
+ bn_sub(pu, vs);
+ bn_sub(pr, ss);
+ }
+ else
+ {
+ bn_add(pu, vs);
+ bn_add(pr, ss);
+ }
+
+ if (bn_is_negative(pu))
+ {
+ bn_clear(ss);
+ bn_sub(ss, pu);
+ ub = bn_bits(ss);
+ }
+ else
+ {
+ ub = bn_bits(pu);
+ }
+
+ if (ub < vb)
+ {
+ shl = ub; // shl,ss used as swap-scratch
+ ub = vb;
+ vb = shl;
+
+ pt = pu;
+ pu = pv;
+ pv = pt;
+
+ pt = ps;
+ ps = pr;
+ pr = pt;
+ }
+ }
- return 0;
-}
+ if (bn_is_negative(pv))
+ {
+ BN_COPY(ss, ps);
+ bn_clear(ps);
+ bn_sub(ps, ss);
+ }
+ if (bn_is_negative(ps))
+ {
+ bn_add(ps, n);
+ }
-// XXX route to bnt_msbit
-//
-#define bn_is_negative(p) (0x1000 & (*(p)))
+ if (bn_cmp(ps, n) >= 0)
+ {
+ bn_sub(ps, n);
+ }
+ BN_COPY(inv, ps);
-// inv stores S during run
-//
-static int bn_modinv(bn_t *inv, const bn_t *a, const bn_t *n)
-{
- bn_t r[ NWORDS ], s[ NWORDS ], u[ NWORDS ], v[ NWORDS ],
- ss[ NWORDS ], vs[ NWORDS ]; // shifted S,V
- unsigned int shl, ub, vb; // shift amount; bitcount
- bn_t *pr = r, *ps = s, *pu = u, *pv = v, *pt;
-
- EC_ASSERT(NULL != inv);
- EC_ASSERT(NULL != a);
- EC_ASSERT(NULL != n);
- EC_ASSERT(bn_cmp(a,n) < 0);
- EC_ASSERT(!bn_is_zero(a,0));
-
- // [1, a]
- // [0, n]
-
- bn_clear(r);
- bn_clear(s);
- BN_LSW(s) = 1;
-
- BN_COPY(u, n);
- BN_COPY(v, a);
-
-// bn_print("U ", u);
-// bn_print("V ", v);
- // ub = bn_bits(u);
- ub = EC_PRIMEBITS; // P521: only ec_prime or ec_order possible
- vb = bn_bits(v);
-// printf("%d,%d\n", (int) ub, (int) vb);
-
- while (1 < vb) {
- EC_ASSERT(ub >= vb);
- shl = ub-vb;
-// printf("< %d\n", shl);
-
- BN_COPY(vs, pv);
- BN_COPY(ss, ps);
- if (shl) {
- bn_shl_n(vs, NWORDS, shl);
- bn_shl_n(ss, NWORDS, shl);
- }
-
- if (bn_is_negative(pv) == bn_is_negative(pu)) {
- bn_sub(pu, vs);
- bn_sub(pr, ss);
- } else {
- bn_add(pu, vs);
- bn_add(pr, ss);
- }
-
-// bn_print("u ", pu);
-// bn_print("r ", pr);
- if (bn_is_negative(pu)) {
- bn_clear(ss);
- bn_sub(ss, pu);
- ub = bn_bits(ss);
- } else {
- ub = bn_bits(pu);
- }
-
- if (ub < vb) {
- shl = ub; // shl,ss used as swap-scratch
- ub = vb;
- vb = shl;
-
- pt = pu;
- pu = pv;
- pv = pt;
-
- pt = ps;
- ps = pr;
- pr = pt;
- }
-// printf("\n");
- }
-
- if (bn_is_negative(pv)) {
- BN_COPY(ss, ps);
- bn_clear(ps);
- bn_sub(ps, ss);
- }
-
- if (bn_is_negative(ps))
- bn_add(ps, n);
-
- if (bn_cmp(ps, n) >= 0)
- bn_sub(ps, n);
- BN_COPY(inv, ps);
-
- return 1;
+ return 1;
}
-
-//-------------------------------------
#if defined(__BIG_ENDIAN)
-
static void bn_read_pt(bn_t *r, const unsigned char *data)
{
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != data);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != data);
- r[0] = 0;
- memmove(((unsigned char *) r) +BNBYTES-EC_PRIMEBYTES,
- data, EC_PRIMEBYTES);
+ r[0] = 0;
+ memmove(((unsigned char *) r) +BNBYTES-EC_PRIMEBYTES,
+ data, EC_PRIMEBYTES);
}
-
// P521: hash does not have unused MS words
//
static void bn_read_hash(bn_t *r, const unsigned char *data)
{
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != data);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != data);
- r[0] = 0;
- memmove(((unsigned char *) r) +BNBYTES-EC_HASHBYTES,
- data, EC_HASHBYTES);
+ r[0] = 0;
+ memmove(((unsigned char *) r) +BNBYTES-EC_HASHBYTES,
+ data, EC_HASHBYTES);
}
-
#else
static void bn_read(bn_t *r, const unsigned char *data, size_t dlen)
{
- bnindex_t i, whole = dlen / sizeof(bn_t),
- rem = dlen % sizeof(bn_t);
- bn_t acc = 0;
+ bnindex_t i, whole = dlen / sizeof(bn_t),
+ rem = dlen % sizeof(bn_t);
+ bn_t acc = 0;
- EC_ASSERT(NULL != r);
- EC_ASSERT(NULL != data);
- EC_ASSERT(dlen <= EC_PRIMEBYTES);
+ EC_ASSERT(NULL != r);
+ EC_ASSERT(NULL != data);
+ EC_ASSERT(dlen <= EC_PRIMEBYTES);
- acc = whole + (!!rem);
- if (acc < NWORDS) { // unused MS words
- acc = NWORDS - acc;
+ acc = whole + (!!rem);
+ if (acc < NWORDS) // unused MS words
+ {
+ acc = NWORDS - acc;
#ifndef BN_POWER64_CLR
- memset(r, 0, acc*sizeof(bn_t));
+ memset(r, 0, acc*sizeof(bn_t));
#else
- bn_clr(r, acc);
+ bn_clr(r, acc);
#endif
- r += acc;
- }
-
- acc = 0;
- if (rem) {
- ++whole;
- } else {
- rem = sizeof(bn_t);
- }
-
- while (0 < whole--) {
- for (i=0; i<rem; ++i)
- acc = (acc <<8) + *(data++);
- *(r++) = acc;
- acc = 0;
- rem = sizeof(bn_t);
- }
-}
+ r += acc;
+ }
+
+ acc = 0;
+ if (rem)
+ {
+ ++whole;
+ }
+ else
+ {
+ rem = sizeof(bn_t);
+ }
+ while (0 < whole--)
+ {
+ for (i=0; i<rem; ++i)
+ {
+ acc = (acc <<8) + *(data++);
+ }
+ *(r++) = acc;
+ acc = 0;
+ rem = sizeof(bn_t);
+ }
+}
static void bn_read_pt(bn_t *r, const unsigned char *data)
{
- return bn_read(r, data, EC_PRIMEBYTES);
+ return bn_read(r, data, EC_PRIMEBYTES);
}
-
static void bn_read_hash(bn_t *r, const unsigned char *data)
{
- return bn_read(r, data, EC_HASHBYTES);
+ return bn_read(r, data, EC_HASHBYTES);
}
#endif /* defined(__BIG_ENDIAN) */
-
//======================================================= EC primitives ====
/* (0,0) is our infinity, since it's not a curve point */
#define ec_is_infinity(px, py, pz) \
@@ -1236,178 +1233,175 @@ static void bn_read_hash(bn_t *r, const unsigned char *data)
#define ec_set_infinity(p) bn_clear(p)
-
-//-------------------------------------
// (x) is transformed back to affine from projective (X*Z)
//
static void ec_projective2affine (bn_t *x, const bn_t *z)
{
- bn_t zinv[ NWORDS ];
+ bn_t zinv[ NWORDS ];
- EC_ASSERT(NULL != x);
- EC_ASSERT(NULL != z);
+ EC_ASSERT(NULL != x);
+ EC_ASSERT(NULL != z);
- EC_ASSERT(!bn_ge_prime(x));
- EC_ASSERT(!bn_ge_prime(z));
+ EC_ASSERT(!bn_ge_prime(x));
+ EC_ASSERT(!bn_ge_prime(z));
- bn_modinv(zinv, z, consts_p()->ec_prime);
- bn_modmul_prime(x, zinv);
+ bn_modinv(zinv, z, consts_p()->ec_prime);
+ bn_modmul_prime(x, zinv);
#ifdef EC_POWER64_RED
- bn_modred_slow(x);
+ bn_modred_slow(x);
#endif
}
-
// returns 1 if result is at infinity, 0 otherwise
//
static int ec_add (bn_t *x1, bn_t *y1, bn_t *z1,
const bn_t *x2, const bn_t *y2, const bn_t *z2)
{
- bn_t a[ NWORDS ], b[ NWORDS ], c[ NWORDS ],
- bs[ NWORDS ], // B^2
- t1[ NWORDS ], t2[ NWORDS ]; // XXX minimize these
- int inf1, inf2;
-
- EC_ASSERT(NULL != x1);
- EC_ASSERT(NULL != y1);
- EC_ASSERT(NULL != z1);
- EC_ASSERT(NULL != x2);
- EC_ASSERT(NULL != y2);
- EC_ASSERT(NULL != z2);
- EC_ASSERT(!bn_ge_prime(x1));
- EC_ASSERT(!bn_ge_prime(y1));
- EC_ASSERT(!bn_ge_prime(z1));
- EC_ASSERT(!bn_ge_prime(x2));
- EC_ASSERT(!bn_ge_prime(y2));
- EC_ASSERT(!bn_ge_prime(z2));
-
- inf1 = ec_is_infinity(x1, y1, z1);
- inf2 = ec_is_infinity(x2, y2, z2);
-
- if (inf2)
- return inf1;
-
- if (inf1) {
- BN_COPY(x1, x2);
- BN_COPY(y1, y2);
- BN_COPY(z1, z2);
- return 0; // (x1,y1,z1) not infinity (checked above)
- }
-
- if (!bn_cmp(x1, x2) && !bn_cmp(y1, y2))
- return ec_double(x1, y1, z1);
+ bn_t a[ NWORDS ], b[ NWORDS ], c[ NWORDS ],
+ bs[ NWORDS ], // B^2
+ t1[ NWORDS ], t2[ NWORDS ]; // XXX minimize these
+ int inf1, inf2;
+
+ EC_ASSERT(NULL != x1);
+ EC_ASSERT(NULL != y1);
+ EC_ASSERT(NULL != z1);
+ EC_ASSERT(NULL != x2);
+ EC_ASSERT(NULL != y2);
+ EC_ASSERT(NULL != z2);
+ EC_ASSERT(!bn_ge_prime(x1));
+ EC_ASSERT(!bn_ge_prime(y1));
+ EC_ASSERT(!bn_ge_prime(z1));
+ EC_ASSERT(!bn_ge_prime(x2));
+ EC_ASSERT(!bn_ge_prime(y2));
+ EC_ASSERT(!bn_ge_prime(z2));
+
+ inf1 = ec_is_infinity(x1, y1, z1);
+ inf2 = ec_is_infinity(x2, y2, z2);
+
+ if (inf2)
+ {
+ return inf1;
+ }
+
+ if (inf1)
+ {
+ BN_COPY(x1, x2);
+ BN_COPY(y1, y2);
+ BN_COPY(z1, z2);
+ return 0; // (x1,y1,z1) not infinity (checked above)
+ }
+
+ if (!bn_cmp(x1, x2) && !bn_cmp(y1, y2))
+ {
+ return ec_double(x1, y1, z1);
+ }
#ifdef EC_POWER64_ALG
- BN_COPY(t1, y1);
- bn_modmul_prime(t1, z2); // t1 = y1 * z2
- BN_COPY(a, y2);
- bn_modmul_prime(a, z1); // A = y2 * z1 - y1 * z2
+ BN_COPY(t1, y1);
+ bn_modmul_prime(t1, z2); // t1 = y1 * z2
+ BN_COPY(a, y2);
+ bn_modmul_prime(a, z1); // A = y2 * z1 - y1 * z2
#ifdef EC_POWER64_RED
- bn_modred_slow(t1);
+ bn_modred_slow(t1);
#endif
- bn_modsub(a, t1);
-
- bn_modmul_prime(x1, z2); // x1 := x1 * z2 orig x1 no longer used
- BN_COPY(b, x2);
- bn_modmul_prime(b, z1);
+ bn_modsub(a, t1);
+ bn_modmul_prime(x1, z2); // x1 := x1 * z2 orig x1 no longer used
+ BN_COPY(b, x2);
+ bn_modmul_prime(b, z1);
#ifdef EC_POWER64_RED
- bn_modred_slow(x1);
+ bn_modred_slow(x1);
#endif
- bn_modsub(b, x1); // B = x2 * z1 - x1 * z2
+ bn_modsub(b, x1); // B = x2 * z1 - x1 * z2
- BN_COPY(bs, b);
- bn_modsqr_prime(bs); // B^2
+ BN_COPY(bs, b);
+ bn_modsqr_prime(bs); // B^2
- BN_COPY(c, a);
- bn_modsqr_prime(c);
- bn_modmul_prime(z1, z2); // z1 = z1 * z2
- bn_modmul_prime(c, z1); // c = A^2 * z1 * z2
+ BN_COPY(c, a);
+ bn_modsqr_prime(c);
+ bn_modmul_prime(z1, z2); // z1 = z1 * z2
+ bn_modmul_prime(c, z1); // c = A^2 * z1 * z2
- bn_modmul_prime(x1, bs); // x1 = B^2 * x1 * z2
- BN_COPY(t2, b);
- bn_modmul_prime(t2, bs); // t2 = B^3
+ bn_modmul_prime(x1, bs); // x1 = B^2 * x1 * z2
+ BN_COPY(t2, b);
+ bn_modmul_prime(t2, bs); // t2 = B^3
#ifdef EC_POWER64_RED
- bn_modred_slow(t2);
- bn_modred_slow(x1);
+ bn_modred_slow(t2);
+ bn_modred_slow(x1);
#endif
- bn_modsub(c, t2);
- bn_modsub(c, x1); // C = A^2 * z1 * z2 - B^3
- bn_modsub(c, x1); // - 2 B^2 * x1 * z1
+ bn_modsub(c, t2);
+ bn_modsub(c, x1); // C = A^2 * z1 * z2 - B^3
+ bn_modsub(c, x1); // - 2 B^2 * x1 * z1
- bn_modmul_prime(z1, t2); // z1 * z2 * B^3
+ bn_modmul_prime(z1, t2); // z1 * z2 * B^3
#ifdef EC_POWER64_RED
- bn_modred_slow(z1);
- bn_modred_slow(c);
+ bn_modred_slow(z1);
+ bn_modred_slow(c);
#endif
- bn_modmul_prime(t1, t2); // (B^3 * y1 * z2)
- // A(B 2 X1 Z2 ? C)
- bn_modsub(x1, c);
- bn_modmul_prime(x1, a); // A * (B^2 * x1 * z2 - C)
+ bn_modmul_prime(t1, t2); // (B^3 * y1 * z2)
+ // A(B 2 X1 Z2 ? C)
+ bn_modsub(x1, c);
+ bn_modmul_prime(x1, a); // A * (B^2 * x1 * z2 - C)
#ifdef EC_POWER64_RED
- bn_modred_slow(x1);
- bn_modred_slow(t1);
+ bn_modred_slow(x1);
+ bn_modred_slow(t1);
#endif
- bn_modsub(x1, t1); // Y = A * (B^2 * x1 * z2 - C) - (B^3 * y1 * z2)
- BN_COPY(y1, x1);
+ bn_modsub(x1, t1); // Y = A * (B^2 * x1 * z2 - C) - (B^3 * y1 * z2)
+ BN_COPY(y1, x1);
- BN_COPY(x1, b);
- bn_modmul_prime(x1, c); // X = B * C
+ BN_COPY(x1, b);
+ bn_modmul_prime(x1, c); // X = B * C
#ifdef EC_POWER64_RED
- bn_modred_slow(x1);
+ bn_modred_slow(x1);
#endif
#else // !EC_POWER64_ALG
- BN_COPY(t1, y1);
- bn_modmul_prime(t1, z2); // t1 = y1 * z2
- BN_COPY(a, y2);
- bn_modmul_prime(a, z1); // A = y2 * z1 - y1 * z2
- bn_modsub(a, t1);
-
- bn_modmul_prime(x1, z2); // x1 := x1 * z2 orig x1 no longer used
- BN_COPY(b, x2);
- bn_modmul_prime(b, z1);
- bn_modsub(b, x1); // B = x2 * z1 - x1 * z2
-
- BN_COPY(bs, b);
- bn_modmul_prime(bs, bs); // B^2
-
- BN_COPY(c, a);
- bn_modmul_prime(c, c);
- bn_modmul_prime(c, z1);
- bn_modmul_prime(c, z2);
-
- BN_COPY(t2, b);
- bn_modadd(t2, x1);
- bn_modadd(t2, x1);
- bn_modmul_prime(t2, bs);
- bn_modsub(c, t2); // C = A^2 * z1 * z2 - B^3
- // - 2 B^2 * x1 * z1
-
- bn_modmul_prime(z1, z2);
- bn_modmul_prime(z1, b);
- bn_modmul_prime(z1, bs); // z1 * z2 * B^3
-
- bn_modmul_prime(t1, b);
- bn_modmul_prime(t1, bs); // (B^3 * y1 * z2)
- // A(B 2 X1 Z2 ? C)
- bn_modmul_prime(x1, bs); // (B^2 * x1 * z2)
- bn_modsub(x1, c);
- bn_modmul_prime(x1, a); // A * (B^2 * x1 * z2 - C)
- bn_modsub(x1, t1);
- BN_COPY(y1, x1); // Y =
-
- BN_COPY(x1, b);
- bn_modmul_prime(x1, c); // X = B * C
+ BN_COPY(t1, y1);
+ bn_modmul_prime(t1, z2); // t1 = y1 * z2
+ BN_COPY(a, y2);
+ bn_modmul_prime(a, z1); // A = y2 * z1 - y1 * z2
+ bn_modsub(a, t1);
+
+ bn_modmul_prime(x1, z2); // x1 := x1 * z2 orig x1 no longer used
+ BN_COPY(b, x2);
+ bn_modmul_prime(b, z1);
+ bn_modsub(b, x1); // B = x2 * z1 - x1 * z2
+
+ BN_COPY(bs, b);
+ bn_modmul_prime(bs, bs); // B^2
+
+ BN_COPY(c, a);
+ bn_modmul_prime(c, c);
+ bn_modmul_prime(c, z1);
+ bn_modmul_prime(c, z2);
+
+ BN_COPY(t2, b);
+ bn_modadd(t2, x1);
+ bn_modadd(t2, x1);
+ bn_modmul_prime(t2, bs);
+ bn_modsub(c, t2); // C = A^2 * z1 * z2 - B^3
+ // - 2 B^2 * x1 * z1
+
+ bn_modmul_prime(z1, z2);
+ bn_modmul_prime(z1, b);
+ bn_modmul_prime(z1, bs); // z1 * z2 * B^3
+
+ bn_modmul_prime(t1, b);
+ bn_modmul_prime(t1, bs); // (B^3 * y1 * z2)
+ // A(B 2 X1 Z2 ? C)
+ bn_modmul_prime(x1, bs); // (B^2 * x1 * z2)
+ bn_modsub(x1, c);
+ bn_modmul_prime(x1, a); // A * (B^2 * x1 * z2 - C)
+ bn_modsub(x1, t1);
+ BN_COPY(y1, x1); // Y =
+
+ BN_COPY(x1, b);
+ bn_modmul_prime(x1, c); // X = B * C
#endif
- return 0;
+ return 0;
}
-
-
-
-//----------------------------------------------------------------------------
// (x,y,z) in projective coordinates
// P521: curve has a==-3
//
@@ -1415,137 +1409,136 @@ static int ec_add (bn_t *x1, bn_t *y1, bn_t *z1,
//
static int ec_double (bn_t *x, bn_t *y, bn_t *z)
{
- bn_t a[ NWORDS ], b[ NWORDS ], c[ NWORDS ], d[ NWORDS ], t[ NWORDS ];
+ bn_t a[ NWORDS ], b[ NWORDS ], c[ NWORDS ], d[ NWORDS ], t[ NWORDS ];
- EC_ASSERT(NULL != x);
- EC_ASSERT(NULL != y);
- EC_ASSERT(NULL != z);
- EC_ASSERT(!bn_ge_prime(x));
- EC_ASSERT(!bn_ge_prime(y));
- EC_ASSERT(!bn_ge_prime(z));
+ EC_ASSERT(NULL != x);
+ EC_ASSERT(NULL != y);
+ EC_ASSERT(NULL != z);
+ EC_ASSERT(!bn_ge_prime(x));
+ EC_ASSERT(!bn_ge_prime(y));
+ EC_ASSERT(!bn_ge_prime(z));
#ifdef EC_POWER64_ALG
- BN_COPY(a, x);
- BN_COPY(d, x);
-
- bn_modadd(a, z);
- bn_modsub(d, z);
- bn_modmul_prime(a, d); // x^2 - z^2
- BN_COPY(d, a);
- bn_modadd(a, a);
- bn_modadd(a, d); // A = 3 * (x^2 - z^2)
- // P521: generally, A = 3 * x^2 - a * z^2
-
- BN_COPY(b, z);
- bn_modmul_prime(b, y); // B = y * z
-
- BN_COPY(c, x);
- bn_modmul_prime(y, b); // y = y * B
- bn_modmul_prime(c, y); // C = x * y * B
-
- BN_COPY(z, b);
- bn_modsqr_prime(z);
- bn_modmul_prime(z, b);
- bn_modadd(z, z);
- bn_modadd(z, z);
- bn_modadd(z, z); // Z = 8 * B^3
+ BN_COPY(a, x);
+ BN_COPY(d, x);
+
+ bn_modadd(a, z);
+ bn_modsub(d, z);
+ bn_modmul_prime(a, d); // x^2 - z^2
+ BN_COPY(d, a);
+ bn_modadd(a, a);
+ bn_modadd(a, d); // A = 3 * (x^2 - z^2)
+ // P521: generally, A = 3 * x^2 - a * z^2
+
+ BN_COPY(b, z);
+ bn_modmul_prime(b, y); // B = y * z
+
+ BN_COPY(c, x);
+ bn_modmul_prime(y, b); // y = y * B
+ bn_modmul_prime(c, y); // C = x * y * B
+
+ BN_COPY(z, b);
+ bn_modsqr_prime(z);
+ bn_modmul_prime(z, b);
+ bn_modadd(z, z);
+ bn_modadd(z, z);
+ bn_modadd(z, z); // Z = 8 * B^3
#ifdef EC_POWER64_RED
- bn_modred_slow(z);
+ bn_modred_slow(z);
#endif
- BN_COPY(t, c);
- bn_modadd(t, t);
- bn_modadd(t, t);
- bn_modadd(t, t);
- BN_COPY(d, a);
- bn_modsqr_prime(d);
+ BN_COPY(t, c);
+ bn_modadd(t, t);
+ bn_modadd(t, t);
+ bn_modadd(t, t);
+ BN_COPY(d, a);
+ bn_modsqr_prime(d);
#ifdef EC_POWER64_RED
- bn_modred_slow(t);
+ bn_modred_slow(t);
#endif
- bn_modsub(d, t); // D = A^2 - 8*C
+ bn_modsub(d, t); // D = A^2 - 8*C
- BN_COPY(x, b);
- bn_modmul_prime(x, d);
- bn_modadd(x, x); // X = 2 * B * D
+ BN_COPY(x, b);
+ bn_modmul_prime(x, d);
+ bn_modadd(x, x); // X = 2 * B * D
#ifdef EC_POWER64_RED
- bn_modred_slow(x);
- bn_modred_slow(d);
+ bn_modred_slow(x);
+ bn_modred_slow(d);
#endif
- bn_modadd(c, c);
- bn_modadd(c, c);
- bn_modsub(c, d);
- bn_modmul_prime(a, c); // (A * (4*C - D))
+ bn_modadd(c, c);
+ bn_modadd(c, c);
+ bn_modsub(c, d);
+ bn_modmul_prime(a, c); // (A * (4*C - D))
- bn_modsqr_prime(y); // (y * B)^2
- bn_modadd(y, y);
- bn_modadd(y, y);
- bn_modadd(y, y); // (8 * y^2 * B^2)
+ bn_modsqr_prime(y); // (y * B)^2
+ bn_modadd(y, y);
+ bn_modadd(y, y);
+ bn_modadd(y, y); // (8 * y^2 * B^2)
#ifdef EC_POWER64_RED
- bn_modred_slow(a);
- bn_modred_slow(y);
+ bn_modred_slow(a);
+ bn_modred_slow(y);
#endif
- bn_modsub(a, y);
- BN_COPY(y, a); // Y = A * (4*C - D) - 8 * y^2 * B^2
+ bn_modsub(a, y);
+ BN_COPY(y, a); // Y = A * (4*C - D) - 8 * y^2 * B^2
#else // !EC_POWER64_ALG
- BN_COPY(a, x);
- BN_COPY(d, z);
-
- bn_modmul_prime(a, x);
- bn_modmul_prime(d, z);
- bn_modsub(a, d);
- BN_COPY(d, a);
- bn_modadd(a, a);
- bn_modadd(a, d); // A = 3 * (x^2 - z^2)
- // P521: generally, A = 3 * x^2 - a * z^2
-
- BN_COPY(b, z);
- bn_modmul_prime(b, y); // B = y * z
-
- BN_COPY(c, y);
- bn_modmul_prime(c, b);
- bn_modmul_prime(c, x); // C = x * y * B
-
- BN_COPY(z, b);
- bn_modmul_prime(z, b);
- bn_modmul_prime(z, b);
- bn_modadd(z, z);
- bn_modadd(z, z);
- bn_modadd(z, z); // Z = 8 * B^3
-
- BN_COPY(t, c);
- bn_modadd(t, t);
- bn_modadd(t, t);
- bn_modadd(t, t);
- BN_COPY(d, a);
- bn_modmul_prime(d, a);
- bn_modsub(d, t); // D = A^2 - 8*C
-
- BN_COPY(x, b);
- bn_modmul_prime(x, d);
- bn_modadd(x, x); // X = 2 * B * D
-
- bn_modadd(c, c);
- bn_modadd(c, c);
- bn_modsub(c, d);
- bn_modmul_prime(a, c); // (A * (4*C - D))
-
- bn_modmul_prime(y, b);
- bn_modmul_prime(y, y);
- bn_modadd(y, y);
- bn_modadd(y, y);
- bn_modadd(y, y); // (8 * y^2 * B^2)
- bn_modsub(a, y);
- BN_COPY(y, a); // Y = A * (4*C - D) - 8 * y^2 * B^2
+ BN_COPY(a, x);
+ BN_COPY(d, z);
+
+ bn_modmul_prime(a, x);
+ bn_modmul_prime(d, z);
+ bn_modsub(a, d);
+ BN_COPY(d, a);
+ bn_modadd(a, a);
+ bn_modadd(a, d); // A = 3 * (x^2 - z^2)
+ // P521: generally, A = 3 * x^2 - a * z^2
+
+ BN_COPY(b, z);
+ bn_modmul_prime(b, y); // B = y * z
+
+ BN_COPY(c, y);
+ bn_modmul_prime(c, b);
+ bn_modmul_prime(c, x); // C = x * y * B
+
+ BN_COPY(z, b);
+ bn_modmul_prime(z, b);
+ bn_modmul_prime(z, b);
+ bn_modadd(z, z);
+ bn_modadd(z, z);
+ bn_modadd(z, z); // Z = 8 * B^3
+
+ BN_COPY(t, c);
+ bn_modadd(t, t);
+ bn_modadd(t, t);
+ bn_modadd(t, t);
+ BN_COPY(d, a);
+ bn_modmul_prime(d, a);
+ bn_modsub(d, t); // D = A^2 - 8*C
+
+ BN_COPY(x, b);
+ bn_modmul_prime(x, d);
+ bn_modadd(x, x); // X = 2 * B * D
+
+ bn_modadd(c, c);
+ bn_modadd(c, c);
+ bn_modsub(c, d);
+ bn_modmul_prime(a, c); // (A * (4*C - D))
+
+ bn_modmul_prime(y, b);
+ bn_modmul_prime(y, y);
+ bn_modadd(y, y);
+ bn_modadd(y, y);
+ bn_modadd(y, y); // (8 * y^2 * B^2)
+ bn_modsub(a, y);
+ BN_COPY(y, a); // Y = A * (4*C - D) - 8 * y^2 * B^2
#endif
- return 0;
+ return 0;
}
-//-------------------------------------
// (x,y) in affine coordinates; z is output only
// returns (x,y,z) in projective coordinates
//
@@ -1557,40 +1550,45 @@ static int ec_double (bn_t *x, bn_t *y, bn_t *z)
//
static int ec_multiply (bn_t *x, bn_t *y, bn_t *z, const bn_t *k)
{
- bn_t px[ NWORDS ], py[ NWORDS ], pz[ NWORDS ];
- unsigned int i;
- bn_t mask = 1;
-
- EC_ASSERT(NULL != x);
- EC_ASSERT(NULL != y);
- EC_ASSERT(NULL != k);
- EC_ASSERT(!bn_ge_prime(x));
- EC_ASSERT(!bn_ge_prime(y));
-
- i=bn_bits(k);
- k += NWORDS-1;
-
- BN_COPY(px, x);
- BN_COPY(py, y);
- bn_clear(x);
- bn_clear(y);
-
- bn_clear(z);
- BN_LSW(z) = 1; // (x,y) -> (x, y, 1) in projective coordinates
- BN_COPY(pz, z); // (px,py) -> (px,py,1)
-
- BN_DUMP(i,x);
- BN_DUMP(i,y);
- BN_DUMP(i,z);
- BN_DUMP(i,px);
- BN_DUMP(i,py);
- BN_DUMP(i,pz);
- while (0 < i--) {
- if (mask & *k)
- ec_add(x, y, z, px, py, pz);
+ bn_t px[ NWORDS ], py[ NWORDS ], pz[ NWORDS ];
+ unsigned int i;
+ bn_t mask = 1;
+
+ EC_ASSERT(NULL != x);
+ EC_ASSERT(NULL != y);
+ EC_ASSERT(NULL != k);
+ EC_ASSERT(!bn_ge_prime(x));
+ EC_ASSERT(!bn_ge_prime(y));
+
+ i=bn_bits(k);
+ k += NWORDS-1;
+
+ BN_COPY(px, x);
+ BN_COPY(py, y);
+ bn_clear(x);
+ bn_clear(y);
+
+ bn_clear(z);
+ BN_LSW(z) = 1; // (x,y) -> (x, y, 1) in projective coordinates
+ BN_COPY(pz, z); // (px,py) -> (px,py,1)
+
+ BN_DUMP(i,x);
+ BN_DUMP(i,y);
+ BN_DUMP(i,z);
+ BN_DUMP(i,px);
+ BN_DUMP(i,py);
+ BN_DUMP(i,pz);
+ while (0 < i--)
+ {
+ if (mask & *k)
+ {
+ ec_add(x, y, z, px, py, pz);
+ }
- if (0 < i)
- ec_double(px, py, pz);
+ if (0 < i)
+ {
+ ec_double(px, py, pz);
+ }
BN_DUMP(i,x);
BN_DUMP(i,y);
@@ -1598,15 +1596,16 @@ static int ec_multiply (bn_t *x, bn_t *y, bn_t *z, const bn_t *k)
BN_DUMP(i,px);
BN_DUMP(i,py);
BN_DUMP(i,pz);
- mask <<= 1;
- if (!mask) {
- --k;
- mask = 1;
- }
- }
+ mask <<= 1;
+ if (!mask)
+ {
+ --k;
+ mask = 1;
+ }
+ }
BN_EXIT();
- return 0;
+ return 0;
}
@@ -1616,47 +1615,57 @@ int ec_verify (const unsigned char *publicpt, /* 2*EC_COORDBYTES */
const unsigned char *hash, /* EC_HASHBYTES */
const unsigned char *signature) /* 2*EC_COORDBYTES */
{
- bn_t r[ NWORDS ], s[ NWORDS ], e[ NWORDS ],
- px[ NWORDS ], py[ NWORDS ], pz[ NWORDS ],
- u1[ NWORDS ], u2[ NWORDS ];
+ bn_t r[ NWORDS ], s[ NWORDS ], e[ NWORDS ],
+ px[ NWORDS ], py[ NWORDS ], pz[ NWORDS ],
+ u1[ NWORDS ], u2[ NWORDS ];
- if ((NULL == publicpt) || (NULL == signature) || (NULL == hash))
- return -1;
+ if ((NULL == publicpt) || (NULL == signature) || (NULL == hash))
+ {
+ return -1;
+ }
- bn_read_pt (r, signature);
- bn_read_pt (s, signature +EC_COORDBYTES);
- bn_read_hash(e, hash);
- bn_read_pt (px, publicpt);
- bn_read_pt (py, publicpt +EC_COORDBYTES);
+ bn_read_pt (r, signature);
+ bn_read_pt (s, signature +EC_COORDBYTES);
+ bn_read_hash(e, hash);
+ bn_read_pt (px, publicpt);
+ bn_read_pt (py, publicpt +EC_COORDBYTES);
- if (bn_ge_order(r) || bn_ge_order(s) ||
- bn_is_zero(s,0) || bn_is_zero(r,0))
- return 0; // assume user messed with signature
+ if (bn_ge_order(r) || bn_ge_order(s) ||
+ bn_is_zero(s,0) || bn_is_zero(r,0))
+ {
+ return 0; // assume user messed with signature
+ }
- if (bn_ge_prime(px) || bn_ge_prime(py) ||
- bn_is_zero(px,0) || bn_is_zero(py,0))
- return -1; // admin fault; should not happen
+ if (bn_ge_prime(px) || bn_ge_prime(py) ||
+ bn_is_zero(px,0) || bn_is_zero(py,0))
+ {
+ return -1; // admin fault; should not happen
+ }
- bn_modinv(u1, s, consts_p()->ec_order); // s no longer needed (NLN)
- BN_COPY(u2, r);
- bn_modmul_order(u2, u1);
- bn_modmul_order(u1, e); // e NLN
+ bn_modinv(u1, s, consts_p()->ec_order); // s no longer needed (NLN)
+ BN_COPY(u2, r);
+ bn_modmul_order(u2, u1);
+ bn_modmul_order(u1, e); // e NLN
- // reuse (e,s) for base multiplication
- BN_COPY(e, consts_p()->prime_px); // (e,s) <- (base point)
- BN_COPY(s, consts_p()->prime_py);
+ // reuse (e,s) for base multiplication
+ BN_COPY(e, consts_p()->prime_px); // (e,s) <- (base point)
+ BN_COPY(s, consts_p()->prime_py);
- ec_multiply(px, py, pz, u2); // (px,py,pz) = u2 * (px,py); u2 NLN
- ec_multiply(e, s, u2, u1); // (s, e, u2) = u1 * (gx,gy); u1 NLN
+ ec_multiply(px, py, pz, u2); // (px,py,pz) = u2 * (px,py); u2 NLN
+ ec_multiply(e, s, u2, u1); // (s, e, u2) = u1 * (gx,gy); u1 NLN
- if (ec_add(px, py, pz, e, s, u2)) // u1 * base + u2 * public
- return 0; // reached infinity (SNH with sig)
+ if (ec_add(px, py, pz, e, s, u2)) // u1 * base + u2 * public
+ {
+ return 0; // reached infinity (SNH with sig)
+ }
- ec_projective2affine(px, pz);
+ ec_projective2affine(px, pz);
- if (bn_ge_order(px))
- bn_sub(px, consts_p()->ec_order); // px mod order
+ if (bn_ge_order(px))
+ {
+ bn_sub(px, consts_p()->ec_order); // px mod order
+ }
- return (! bn_cmp(r, px));
+ return (! bn_cmp(r, px));
}
diff --git a/src/securerom/hw_utils.C b/src/securerom/hw_utils.C
index 19d4ee947..7adcb35a8 100644
--- a/src/securerom/hw_utils.C
+++ b/src/securerom/hw_utils.C
@@ -22,13 +22,9 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/****************************************************************************
- *
- ****************************************************************************/
-#include <hw_utils.h>
-#include <status_codes.h>
-/****************************************************************************/
+#include <securerom/hw_utils.H>
+#include <securerom/status_codes.H>
#ifdef EMULATE_HW
@@ -36,187 +32,187 @@
#include <unistd.h>
#include <sys/mman.h>
#include <limits.h>
-#include <stdint.h> /* uint_fast8_t, uintN_t */
-#include <inttypes.h>
+#include <stdint.h> /* uint_fast8_t, uintN_t */
+#include "inttypes.H"
hw_settings HW;
-/****************************************************************************/
-void HW_Init (void) {
- /* Open the file that will be used to fill the memory contents of the mmap */
- HW.mfd = open ("/dev/zero", O_RDWR, 0);
- if (HW.mfd < 0) {
- printf ("HW_Init: can't create memory file");
- exit(1);
- }
+void HW_Init (void)
+{
+ // Open the file that will be used to fill the memory contents of the mmap
+ HW.mfd = open ("/dev/zero", O_RDWR, 0);
+ if (HW.mfd < 0)
+ {
+ printf ("HW_Init: can't create memory file");
+ exit(1);
+ }
/* Allocate Memory */
#ifdef HOST_64
- HW.data = (uint8_t*) mmap64 (0, TOTAL_TEST_MEMORY,
- PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, HW.mfd, 0);
+ HW.data = (uint8_t*) mmap64 (0, TOTAL_TEST_MEMORY,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE, HW.mfd, 0);
#else
- HW.data = (uint8_t*) mmap (0, TOTAL_TEST_MEMORY,
- PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, HW.mfd, 0);
+ HW.data = (uint8_t*) mmap (0, TOTAL_TEST_MEMORY,
+ PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE,
+ HW.mfd, 0);
#endif
- if ((uint32_t) HW.data == -1) {
- printf ("Unable to allocate HW Memory of size %d", TOTAL_TEST_MEMORY);
- HW_Free();
- exit(1);
- }
- HW.memory = HW.data+0x1000-((uint32_t)HW.data&0xfff);
+ if ((uint32_t) HW.data == -1)
+ {
+ printf ("Unable to allocate HW Memory of size %d", TOTAL_TEST_MEMORY);
+ HW_Free();
+ exit(1);
+ }
+ HW.memory = HW.data+0x1000-((uint32_t)HW.data&0xfff);
}
-/****************************************************************************/
void HW_Free (void)
{
- close (HW.mfd);
+ close (HW.mfd);
}
-/****************************************************************************/
void Log (uint64_t code) {
- mtspr_SCRATCH2 (code);
+ mtspr_SCRATCH2 (code);
+}
+
+void Check_Stop (const char* msg)
+{
+ printf ("CHECK STOP '%s'\n", msg);
+ printf ("SCRATCH3= 0x%08llX\n", mfspr_SCRATCH3());
+ exit(FAIL);
}
-/****************************************************************************/
-void Check_Stop (char* msg) {
- printf ("CHECK STOP '%s'\n", msg);
- printf ("SCRATCH3= 0x%08llX\n", mfspr_SCRATCH3());
- exit(FAIL);
+void Error_Stop (uint64_t code, const char* msg)
+{
+ mtspr_SCRATCH3 (ERROR_EVENT|code);
+ Check_Stop (msg);
}
-/****************************************************************************/
-void Error_Stop (uint64_t code, char* msg) {
- mtspr_SCRATCH3 (ERROR_EVENT|code);
- Check_Stop (msg);
+void assem_DCBI (uint64_t addr)
+{
+ addr = physical_addr(addr)&CACHE_MASK;
+ memset(Convert_Mem_Addr(addr),0xff,CACHE_LINE); // destroys contents in model
}
-/****************************************************************************/
-void assem_DCBI (uint64_t addr) {
- addr = physical_addr(addr)&CACHE_MASK;
- memset(Convert_Mem_Addr(addr),0xff,CACHE_LINE); // destroys contents in model
- }
-/****************************************************************************/
void assem_DCBZ (uint64_t addr) {
- addr = physical_addr(addr)&CACHE_MASK;
- memset(Convert_Mem_Addr(addr),0,CACHE_LINE);
+ addr = physical_addr(addr)&CACHE_MASK;
+ memset(Convert_Mem_Addr(addr),0,CACHE_LINE);
}
-/****************************************************************************/
+
void assem_DCBST (uint8_t* addr) {}
-/****************************************************************************/
void assem_ICBI (uint64_t* addr) {}
-/****************************************************************************/
void assem_SYNC (void) {}
-/****************************************************************************/
void assem_ISYNC (void) {}
-/****************************************************************************/
-void mtspr_HRMOR (uint64_t addr) {
- HW.HRMOR = addr & HRMOR_MASK;
-}
-
-/****************************************************************************/
-//uint64_t mfspr_HRMOR (void) {
-// return HW.HRMOR;
-//}
-
-/****************************************************************************/
-
-/****************************************************************************/
-uint64_t getscom_FSP_BAR_value (uint64_t base) {
- return HW.FSP_BAR.value;
-}
-
-/****************************************************************************/
-uint64_t getscom_FSP_BAR_mask (uint64_t base) {
- return HW.FSP_BAR.mask;
+void mtspr_HRMOR (uint64_t addr)
+{
+ HW.HRMOR = addr & HRMOR_MASK;
}
-/****************************************************************************/
-void getscom_HW_ECID (uint64_t base, uint8_t* buf) {
- memcpy(buf, HW.ECID, ECID_SIZE);
+uint64_t getscom_FSP_BAR_value (uint64_t base)
+{
+ return HW.FSP_BAR.value;
}
-/****************************************************************************/
-void getscom_PIBMEM_HW_Key_Hash (uint64_t base, uint8_t* buf) {
- memcpy(buf, HW.PIBMEM_HW_KEY_HASH, SHA512_DIGEST_SIZE);
+uint64_t getscom_FSP_BAR_mask (uint64_t base)
+{
+ return HW.FSP_BAR.mask;
}
-/****************************************************************************/
-uint8_t* Convert_Mem_Addr (uint64_t addr) {
- if (addr >= TEST_SYSTEM_MEMORY) return NULL;
- return HW.memory+addr;
+void getscom_HW_ECID (uint64_t base, uint8_t* buf)
+{
+ memcpy(buf, HW.ECID, ECID_SIZE);
}
-/****************************************************************************/
-uint64_t physical_addr (uint64_t addr) {
- if (addr & HRMOR_IGNORE) addr = PHYSICAL(addr);
- else addr = PHYSICAL(addr) | HW.HRMOR;
- return addr;
+uint8_t* Convert_Mem_Addr (uint64_t addr)
+{
+ if (addr >= TEST_SYSTEM_MEMORY)
+ {
+ return NULL;
+ }
+ return HW.memory+addr;
}
-/****************************************************************************/
-uint64_t Convert_Mem_Offset (uint8_t* addr) {
- if (addr < HW.memory) return 0;
- return (uint64_t)(uint32_t)(addr-HW.memory);
+uint64_t physical_addr (uint64_t addr)
+{
+ if (addr & HRMOR_IGNORE)
+ {
+ addr = PHYSICAL(addr);
+ }
+ else
+ {
+ addr = PHYSICAL(addr) | HW.HRMOR;
+ }
+ return addr;
+}
+
+uint64_t Convert_Mem_Offset (uint8_t* addr)
+{
+ if (addr < HW.memory)
+ {
+ return 0;
+ }
+ return (uint64_t)(uint32_t)(addr-HW.memory);
}
-/****************************************************************************/
-uint16_t GET16(uint16_t data) {
+uint16_t GET16(uint16_t data)
+{
#ifdef __BIG_ENDIAN
- return data;
+ return data;
#endif
#ifdef __LITTLE_ENDIAN
- return ((data&0x00FF)<<8
- |(data&0xFF00)>>8
- );
+ return ((data&0x00FF)<<8
+ | (data&0xFF00)>>8
+ );
#endif
}
-/****************************************************************************/
-uint32_t GET32 (uint32_t data) {
+uint32_t GET32 (uint32_t data)
+{
#ifdef __BIG_ENDIAN
- return data;
+ return data;
#endif
#ifdef __LITTLE_ENDIAN
- return ((data&0x000000FF)<<24
- |(data&0x0000FF00)<<8
- |(data&0x00FF0000)>>8
- |(data&0xFF000000)>>24
- );
+ return ((data&0x000000FF)<<24
+ |(data&0x0000FF00)<<8
+ |(data&0x00FF0000)>>8
+ |(data&0xFF000000)>>24
+ );
#endif
}
-/****************************************************************************/
-uint64_t GET64 (uint64_t data) {
+uint64_t GET64 (uint64_t data)
+{
#ifdef __BIG_ENDIAN
- return data;
+ return data;
#endif
#ifdef __LITTLE_ENDIAN
- return ((data&0x00000000000000FFull)<<(7*8)
- |(data&0x000000000000FF00ull)<<(5*8)
- |(data&0x0000000000FF0000ull)<<(3*8)
- |(data&0x00000000FF000000ull)<<(1*8)
- |(data&0x000000FF00000000ull)>>(1*8)
- |(data&0x0000FF0000000000ull)>>(3*8)
- |(data&0x00FF000000000000ull)>>(5*8)
- |(data&0xFF00000000000000ull)>>(7*8)
- );
+ return ((data&0x00000000000000FFull)<<(7*8)
+ |(data&0x000000000000FF00ull)<<(5*8)
+ |(data&0x0000000000FF0000ull)<<(3*8)
+ |(data&0x00000000FF000000ull)<<(1*8)
+ |(data&0x000000FF00000000ull)>>(1*8)
+ |(data&0x0000FF0000000000ull)>>(3*8)
+ |(data&0x00FF000000000000ull)>>(5*8)
+ |(data&0xFF00000000000000ull)>>(7*8)
+ );
#endif
}
#else
-void __attribute__((noreturn)) Check_Stop(void) {
- //do not use XSCOM as the XSCOM base is not known for sure
+void __attribute__((noreturn)) Check_Stop(void)
+{
+ //do not use XSCOM as the XSCOM base is not known for sure
- //set AVP_out to (optionally) cause secure checkstop
- mtspr(SPRC,SPRC_AVP_out);
- mtspr(SPRD,-1LL);
+ //set AVP_out to (optionally) cause secure checkstop
+ mtspr(SPRC,SPRC_AVP_out);
+ mtspr(SPRD,-1LL);
- asm volatile(" li 0,0 \n"
- " mtmsr 0 \n" //ensure there is no error handler so it will checkstop instead
- " lis 0,-1107 \n"
- " stdcix 0,0,0 \n" //store to invalid address
- " eieio ");
- for(;;) {}
+ asm volatile(" li 0,0 \n"
+ " mtmsr 0 \n" //ensure there is no error handler so it will checkstop instead
+ " lis 0,-1107 \n"
+ " stdcix 0,0,0 \n" //store to invalid address
+ " eieio ");
+ for(;;) {}
}
-#endif //emulate_hw
+#endif //EMULATE_HW
diff --git a/src/securerom/inttypes.H b/src/securerom/inttypes.H
index 397732961..5da83836f 100644
--- a/src/securerom/inttypes.H
+++ b/src/securerom/inttypes.H
@@ -22,6 +22,7 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
#define uint_fast8_t uint8_t
#ifndef BYTE_ORDER
diff --git a/src/securerom/makefile b/src/securerom/makefile
index 4b3a5a3cf..e1c5cc8cf 100644
--- a/src/securerom/makefile
+++ b/src/securerom/makefile
@@ -23,222 +23,27 @@
#
# IBM_PROLOG_END_TAG
-bootrom := bootrom
-bootrom_bin = $(bootrom).bin
-bootrom_dis = $(bootrom).dis
-#bootrom_srec = $(bootrom).srec
+ROOTPATH = ../..
-bootrom_vhdl = ../vhdl/tpc_secr_rom_pkg.vhdl
+COMMONFLAGS += -DBYTE_ORDER=BIG_ENDIAN
+COMMONFLAGS += -DBN_POWER64_MUL
+COMMONFLAGS += -DBN_POWER64_CMP
+COMMONFLAGS += -DBN_POWER64_CPY
+COMMONFLAGS += -DBN_POWER64_CLR
+COMMONFLAGS += -DEC_POWER64_RED
+COMMONFLAGS += -DEC_POWER64_ALG
+COMMONFLAGS += -DSHA512_FIX
-bootrom_nm = $(bootrom).nm
+LDFLAGS += -N
-LDSCRIPT = bootrom.lds
+ASMFLAGS += -D__ASSEMBLER__
-HOSTTYPE ?= $(shell uname -p)
-CELLSIZE ?= 64
+OBJS += branchtable.o
+OBJS += ROM.o
+OBJS += sha512.o
+OBJS += ecverify.o
+OBJS += hw_utils.o
-ifeq ($(HOSTTYPE),powerpc)
-CROSS ?= powerpc-ibm-aix6.1.0.0-
-ONLY_CC = $(CROSS)gcc -mpowerpc64 -maix64 -Wa,-mANY
-ONLY_AS = $(CROSS)as -m$(CELLSIZE)
-ONLY_LD = $(CROSS)ld -melf$(CELLSIZE)ppc
-OBJCOPY ?= $(CROSS)objcopy
-OBJDUMP ?= $(CROSS)objdump
-else
-CROSS ?= powerpc-linux-gnu-
-ONLY_CC = $(CROSS)gcc -m64 -Wa,-mregnames
-ONLY_AS = $(CROSS)as -m64 -mregnames
-ONLY_LD = $(CROSS)ld -melf64ppc
-OBJCOPY ?= $(CROSS)objcopy
-OBJDUMP ?= $(CROSS)objdump
-endif
+OPT_LEVEL = -Os
-
-# Verbose level:
-# V=0 means completely silent
-# V=1 means brief output
-# V=2 means full verbose output
-V ?= 2
-
-ifeq ($(V),0)
-Q := @
-MAKEFLAGS += --silent
-MAKE += -s
-endif
-
-ifeq ($(V),1)
-MAKEFLAGS += --silent
-MAKE += -s
-CC = printf "\t[CC]\t$@\n"; $(ONLY_CC)
-AS = printf "\t[AS]\t$@\n"; $(ONLY_AS)
-LD = printf "\t[LD]\t$@\n"; $(ONLY_LD)
-CLEAN = printf "\t[CLEAN]\t%s\n" "$(DIRECTORY)$$dir"
-else
-CC = $(ONLY_CC)
-AS = $(ONLY_AS)
-LD = $(ONLY_LD)
-CLEAN = echo -n
-endif
-
-# need version >= 1_0_0
-#OPENSSL ?= ~/openssl/openssl-1.0.0/bin/openssl
-#SREC_CAT ?= srec_cat
-
-CPPFLAGS += -DCONFIG_AWAN \
- -I./src/ -I./include/ \
- -DCELLSIZE=$(CELLSIZE) \
- -DBYTE_ORDER=BIG_ENDIAN \
- -g \
-
-#CPPFLAGS += -DEC_POWER64_ASM
-CPPFLAGS += -DBN_POWER64_MUL
-CPPFLAGS += -DBN_POWER64_CMP
-CPPFLAGS += -DBN_POWER64_CPY
-CPPFLAGS += -DBN_POWER64_CLR
-CPPFLAGS += -DEC_POWER64_RED
-#CPPFLAGS += -DBN_POWER64_SQR
-CPPFLAGS += -DEC_POWER64_ALG
-#CPPFLAGS += -DBN_POWER64_DBG
-CPPFLAGS += -DSHA512_FIX
-
-OBJDIR = obj
-
-ifeq ($(MAMBO),yes)
-CPPFLAGS += -DCONFIG_MAMBO
-bootrom := bootrom_4mambo
-OBJDIR = mambo
-endif
-
-asm_srcs = src/branchtable.S
-c_srcs = src/ROM.c src/sha512.c src/ecverify.c
-c_srcs += src/memmove.c src/memcmp.c src/hw_utils.c
-#c_srcs += src/memset.c src/memcpy.c
-
-CPPFLAGS += -DCONFIG_SOFTWARE_CRYPTO
-
-srcs = $(asm_srcs) $(c_srcs)
-objs = $(subst src/,$(OBJDIR)/,$(asm_srcs:.S=.o) $(c_srcs:.c=.o))
-deps = $(subst src/,$(OBJDIR)/,$(asm_srcs:.S=.d) $(c_srcs:.c=.d))
-
-CFLAGS ?= -W -Os -fno-builtin -ffreestanding -nostdinc -mno-toc \
- -msoft-float -mno-altivec -mabi=no-altivec -Wall -mregnames \
- $(CPPFLAGS)
-
-ASFLAGS += $(CPPFLAGS) -Wa,-mregnames -D__ASSEMBLER__
-
-LDFLAGS = -nostdlib -N
-
-
-default:
- $(MAKE) all
- $(MAKE) MAMBO=yes bootrom_4mambo.dis bootrom_4mambo.bin
-
-$(OBJDIR):
- @if [ -d $(OBJDIR) ] ; then true; else mkdir -p $(OBJDIR); fi
-
-all: $(bootrom_dis) $(bootrom_bin) $(bootrom_vhdl)
-
-
-NODEPS = clean distclean binclean
-ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
--include $(deps)
-endif
-
-
-## This was to create a selfsigned rom code but now it is no longer selfsigned :
-
-#ec_private_key.pem:
-# $(OPENSSL) ecparam -name secp521r1 -genkey -out ec_private_key.pem
-
-#ec_private_key.pem: ec_private_key.pkcs8
-# $(OPENSSL) pkcs8 -inform DER -nocrypt -in ec_private_key.pkcs8 -out ec_private_key.pem
-#ec_private_key.pkcs8:
-# ./ecdsasig.x86 -r -g x > ec_private_key.pkcs8
-
-#ec_public_key.der: ec_private_key.pem
-# $(OPENSSL) ec -in ec_private_key.pem -pubout -outform DER -out ec_public_key.der
-
-#$(bootrom).stage1: $(objs) $(gen_hdrs) $(prism_hdrs) src/dummy_header.o src/dummy_hash.o
-# $(LD) $(LDFLAGS) -o $@ $(objs) src/dummy_header.o src/dummy_hash.o
-
-#$(bootrom).signed.bin: $(bootrom).stage1
-# $(OBJCOPY) -j .text -j .data -O binary $^ $@
-
-#dummy_header.bin: $(bootrom).stage1
-# $(OBJCOPY) -j .image_header -O binary $^ $@
-
-#$(bootrom).signed.sig: $(bootrom).signed.bin ec_private_key.pem
-# $(OPENSSL) dgst -sign ec_private_key.pem -sha512 $^ > $@
-
-#image_header.bin: ec_public_key.der $(bootrom).signed.sig src/dummy_header.o dummy_header.bin
-# ./asn1extract_pubkey.pl ec_public_key.der > image_header.bin
-# dd bs=132 count=2 if=/dev/zero >> image_header.bin
-# ./asn1extract.pl bootrom.signed.sig | xxd -r -p >> image_header.bin
-# dd bs=132 count=2 if=/dev/zero >> image_header.bin
-# dd bs=1 skip=792 count=88 if=dummy_header.bin >> image_header.bin
-
-#image_header.o: image_header.bin
-# $(OBJCOPY) -I binary -O elf64-powerpc -B powerpc --rename-section .data=.image_header --redefine-sym _binary_image_header_bin_start=rom_image_header image_header.bin image_header.o
-
-#$(bootrom).stage2: $(objs) $(gen_hdrs) $(prism_hdrs) image_header.o src/dummy_hash.o
-# $(LD) $(LDFLAGS) -o $@ $(objs) image_header.o src/dummy_hash.o
-
-#bootrom.hashed.bin: $(bootrom).stage2
-# $(OBJCOPY) -j .image_hash -j .text -j .data -O binary $^ $@
-
-#bootrom.hashed.hash: bootrom.hashed.bin
-# $(OPENSSL) dgst -sha512 bootrom.hashed.bin | sed -e "s/.* //" | xxd -r -p > bootrom.hashed.hash
-
-#rom_hash.o: bootrom.hashed.hash
-# $(OBJCOPY) -I binary -O elf64-powerpc -B powerpc \
-# --rename-section .data=.rom_hash \
-# --redefine-sym _binary_bootrom_hashed_hash_start=rom_hash \
-# bootrom.hashed.hash rom_hash.o
-
-#$(bootrom): $(objs) $(gen_hdrs) $(prism_hdrs) image_header.o rom_hash.o
-# $(LD) $(LDFLAGS) -o $@ $(objs) image_header.o rom_hash.o
-
-$(bootrom): $(objs) $(LDSCRIPT)
- $(LD) $(LDFLAGS) -T$(LDSCRIPT) -o $@ $(objs)
-
-$(bootrom_dis): $(bootrom)
- $(OBJDUMP) -j .branchtable -j .text -j .data -j .toc --source $^ > $@
-
-#$(bootrom_srec): $(bootrom)
-# $(OBJCOPY) --change-addresses -0xff80000 $^ -O srec $@
-
-$(bootrom_bin): $(bootrom)
- $(OBJCOPY) -j .branchtable -j .text -j .data -j .toc -O binary $^ $@
-
-$(bootrom_vhdl): $(bootrom_bin) convVhdl.pl
- ./convVhdl.pl $^ > $@
-
-$(OBJDIR)/%.o: src/%.S $(OBJDIR)/%.d
- $(CC) $(ASFLAGS) -c $< -o $@
-
-$(OBJDIR)/%.o: src/%.c $(OBJDIR)/%.d
- $(CC) $(CFLAGS) -c $< -o $@
-
-$(OBJDIR)/%.d: src/%.S Makefile $(OBJDIR)
- $(CC) -MM $(ASFLAGS) $< | sed 's,\(\S*\)\.o[ :]*,$(OBJDIR)/\1.o $(OBJDIR)/\1.d : ,g' > $@
-
-$(OBJDIR)/%.d: src/%.c Makefile $(OBJDIR)
- $(CC) -MM $(CFLAGS) $< | sed 's,\(\S*\)\.o[ :]*,$(OBJDIR)/\1.o $(OBJDIR)/\1.d : ,g' > $@
-
-#ecdsa: src/ecdsa.c src/ecverify.c
-# gcc -W -Os -fno-builtin -ffreestanding -nostdinc -msoft-float -mno-altivec -mabi=no-altivec -Wall -I./src/ -I./include/ -o ecdsa src/ecdsa.c src/ecverify.c
-
-clean:
- $(RM) -r *~ obj mambo
-# ec_public_key.der \
-# $(bootrom).stage1 $(bootrom).signed.bin $(bootrom).signed.sig dummy_header.bin image_header.bin image_header.o\
-# $(bootrom).stage2 $(bootrom).hashed.bin $(bootrom).hashed.hash rom_hash.o
-
-distclean: clean
- @$(MAKE) binclean
- @$(MAKE) MAMBO=yes binclean
-
-binclean:
- $(RM) $(bootrom) $(bootrom_bin) $(bootrom_dis)
-
-.PHONY: default all clean distclean binclean
+include ${ROOTPATH}/config.mk
diff --git a/src/securerom/sha512.C b/src/securerom/sha512.C
index 820ead264..9ec230f4f 100644
--- a/src/securerom/sha512.C
+++ b/src/securerom/sha512.C
@@ -30,105 +30,100 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
-#include <sha512.h>
+#include <securerom/sha512.H>
/* Initial hash value HASH(32byte) for SHA-512 */
-const uint64_t sha512_initial_hash_value[8] = {
- 0x6a09e667f3bcc908ULL,
- 0xbb67ae8584caa73bULL,
- 0x3c6ef372fe94f82bULL,
- 0xa54ff53a5f1d36f1ULL,
- 0x510e527fade682d1ULL,
- 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL,
- 0x5be0cd19137e2179ULL
+extern "C"
+const uint64_t sha512_initial_hash_value[8] =
+{
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
};
/* Hash constant words K for SHA-384 and SHA-512: */
-const uint64_t K512[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
+extern "C"
+const uint64_t K512[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
};
-
-
-#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
-
-
+#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
/*
* Macro for incrementally adding the unsigned 64-bit integer n to the
* unsigned 128-bit integer (represented using a two-element array of
* 64-bit words):
*/
-#define ADDINC128(w,n) { \
- (w)[0] += (uint64_t)(n); \
- if ((w)[0] < (n)) { \
- (w)[1]++; \
- } \
+#define ADDINC128(w,n) \
+{ \
+ (w)[0] += (uint64_t)(n); \
+ if ((w)[0] < (n)) \
+ { \
+ (w)[1]++; \
+ } \
}
-
-
/* Shift-right (used in SHA-512): */
-#define R(b,x) ((x) >> (b))
-
+#define R(b,x) ((x) >> (b))
/* 64-bit Rotate-right (used in SHA-512): */
-#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
-
-
+#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
/* Two of six logical functions used in SHA-512: */
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
/* Four of six logical functions used in SHA-512: */
-#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
-#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
-#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
-#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
+#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
+#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
static void SHA512_Last(SHA512_CTX*);
static void SHA512_Transform(SHA512_CTX*, const uint64_t *);
@@ -137,346 +132,270 @@ static void SHA512_Transform(SHA512_CTX*, const uint64_t *);
* Constant used by SHA256/384/512_End() functions for converting the
* digest to a readable hexadecimal character string:
*/
-
-static inline void bcopy(const void * SRC, void* DST, size_t length){
+static inline void bcopy(const void * SRC, void* DST, size_t length)
+{
unsigned char * source = (unsigned char *) SRC;
unsigned char * destination = (unsigned char *) DST;
- for( ; length ; length--){
+ for( ; length ; length--)
+ {
*destination++ = *source++;
}
}
static inline void bzero(void * DST, size_t length){
unsigned char * destination = (unsigned char *) DST;
- for( ; length ; length--){
+ for( ; length ; length--)
+ {
*destination++=0x00;
}
}
-// unused:
-//static inline int tstrlen(const void * SRC){
-// unsigned char * source = (unsigned char *) SRC;
-// int length=0;
-// while(source[length]!=0x00){
-// length++;
-// }
-// return length;
-//}
-
-
/*** SHA-512: *********************************************************/
asm(".globl .L.SHA512_Init");
-void SHA512_Init(SHA512_CTX* context) {
- if (context == (SHA512_CTX*)0) {
- return;
- }
-
- uint64_t* sha512_initial_hash_value_p;
- #ifdef EMULATE_HW
- sha512_initial_hash_value_p = sha512_initial_hash_value;
- #else
- //selftest_p = &selftest; //this line would introduce a absolute address in the toc
- asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
- "sub %0,r2,%0 \n\t" // because subi does not work
- "addi %0,%0,(sha512_initial_hash_value-0x8000)@l" : "=r" (sha512_initial_hash_value_p) );
- #endif
-
- bcopy(sha512_initial_hash_value_p, context->state, SHA512_DIGEST_LENGTH);
- bzero(context->buffer, SHA512_BLOCK_LENGTH);
- context->bitcount[0] = context->bitcount[1] = 0;
-}
+void SHA512_Init(SHA512_CTX* context)
+{
+ if (context == (SHA512_CTX*)0)
+ {
+ return;
+ }
+ uint64_t* sha512_initial_hash_value_p;
+#ifdef EMULATE_HW
+ sha512_initial_hash_value_p = sha512_initial_hash_value;
+#else
+ asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
+ "sub %0,2,%0 \n\t" // because subi does not work
+ "addi %0,%0,(sha512_initial_hash_value-0x8000)@l" : "=r" (sha512_initial_hash_value_p) );
+#endif
-static void SHA512_Transform(SHA512_CTX* context, const uint64_t* data) {
- uint64_t a, b, c, d, e, f, g, h, s0, s1;
- uint64_t T1, T2, *W512 = (uint64_t*)context->buffer;
- int j;
-
- uint64_t* K512_p;
- #ifdef EMULATE_HW
- K512_p = K512;
- #else
- //selftest_p = &selftest; //this line would introduce a absolute address in the toc
- asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
- "sub %0,r2,%0 \n\t" // because subi does not work
- "addi %0,%0,(K512-0x8000)@l" : "=r" (K512_p) );
- #endif
-
- /* Initialize registers with the prev. intermediate value */
- a = context->state[0];
- b = context->state[1];
- c = context->state[2];
- d = context->state[3];
- e = context->state[4];
- f = context->state[5];
- g = context->state[6];
- h = context->state[7];
-
- j = 0;
- do {
- /* Apply the SHA-512 compression function to update a..h with copy */
- T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512_p[j] + (W512[j] = *data++);
- T2 = Sigma0_512(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 16);
-
- do {
- /* Part of the message block expansion: */
- s0 = W512[(j+1)&0x0f];
- s0 = sigma0_512(s0);
- s1 = W512[(j+14)&0x0f];
- s1 = sigma1_512(s1);
-
- /* Apply the SHA-512 compression function to update a..h */
- T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512_p[j] +
- (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
- T2 = Sigma0_512(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 80);
-
- /* Compute the current intermediate hash value */
- context->state[0] += a;
- context->state[1] += b;
- context->state[2] += c;
- context->state[3] += d;
- context->state[4] += e;
- context->state[5] += f;
- context->state[6] += g;
- context->state[7] += h;
-
- /* Clean up */
- a = b = c = d = e = f = g = h = T1 = T2 = 0;
+ bcopy(sha512_initial_hash_value_p, context->state, SHA512_DIGEST_LENGTH);
+ bzero(context->buffer, SHA512_BLOCK_LENGTH);
+ context->bitcount[0] = context->bitcount[1] = 0;
}
+static void SHA512_Transform(SHA512_CTX* context, const uint64_t* data)
+{
+ uint64_t a, b, c, d, e, f, g, h, s0, s1;
+ uint64_t T1, T2, *W512 = (uint64_t*)context->buffer;
+ int j;
+
+ uint64_t* K512_p;
+#ifdef EMULATE_HW
+ K512_p = K512;
+#else
+ asm volatile("li %0,(__toc_start)@l ### %0 := base+0x8000 \n\t" // because li does not work
+ "sub %0,2,%0 \n\t" // because subi does not work
+ "addi %0,%0,(K512-0x8000)@l" : "=r" (K512_p) );
+#endif
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+ /* Apply the SHA-512 compression function to update a..h with copy */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512_p[j] + (W512[j] = *data++);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W512[(j+1)&0x0f];
+ s0 = sigma0_512(s0);
+ s1 = W512[(j+14)&0x0f];
+ s1 = sigma1_512(s1);
+
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512_p[j] +
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
asm(".globl .L.SHA512_Update");
-void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
- unsigned int freespace, usedspace;
-
- if (len == 0) {
- /* Calling with no data is valid - we do nothing */
- return;
- }
-
- /* Sanity check: */
- //assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
-
- usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
- if (usedspace > 0) {
- /* Calculate how much free space is available in the buffer */
- freespace = SHA512_BLOCK_LENGTH - usedspace;
-
- if (len >= freespace) {
- /* Fill the buffer completely and process it */
- bcopy(data, &context->buffer[usedspace], freespace);
- ADDINC128(context->bitcount, freespace << 3);
- len -= freespace;
- data += freespace;
- SHA512_Transform(context, (uint64_t*)context->buffer);
- } else {
- /* The buffer is not yet full */
- bcopy(data, &context->buffer[usedspace], len);
- ADDINC128(context->bitcount, len << 3);
- /* Clean up: */
- usedspace = freespace = 0;
- return;
- }
- }
- while (len >= SHA512_BLOCK_LENGTH) {
- /* Process as many complete blocks as we can */
- SHA512_Transform(context, (const uint64_t*)data);
- ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
- len -= SHA512_BLOCK_LENGTH;
- data += SHA512_BLOCK_LENGTH;
- }
- if (len > 0) {
- /* There's left-overs, so save 'em */
- bcopy(data, context->buffer, len);
- ADDINC128(context->bitcount, len << 3);
- }
- /* Clean up: */
- usedspace = freespace = 0;
+void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len)
+{
+ unsigned int freespace, usedspace;
+
+ if (len == 0)
+ {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0)
+ {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace)
+ {
+ /* Fill the buffer completely and process it */
+ bcopy(data, &context->buffer[usedspace], freespace);
+ ADDINC128(context->bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512_Transform(context, (uint64_t*)context->buffer);
+ }
+ else
+ {
+ /* The buffer is not yet full */
+ bcopy(data, &context->buffer[usedspace], len);
+ ADDINC128(context->bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA512_BLOCK_LENGTH)
+ {
+ /* Process as many complete blocks as we can */
+ SHA512_Transform(context, (const uint64_t*)data);
+ ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+ len -= SHA512_BLOCK_LENGTH;
+ data += SHA512_BLOCK_LENGTH;
+ }
+ if (len > 0)
+ {
+ /* There's left-overs, so save 'em */
+ bcopy(data, context->buffer, len);
+ ADDINC128(context->bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
}
-static void SHA512_Last(SHA512_CTX* context) {
- unsigned int usedspace;
+static void SHA512_Last(SHA512_CTX* context)
+{
+ unsigned int usedspace;
- usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
- if (usedspace > 0) {
- /* Begin padding with a 1 bit: */
- context->buffer[usedspace++] = 0x80;
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0)
+ {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
#if SHA512_FIX
- if (usedspace < SHA512_SHORT_BLOCK_LENGTH) {
- /* Set-up for the last transform: */
- bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
- } else if (usedspace > SHA512_SHORT_BLOCK_LENGTH) {
- if (usedspace < SHA512_BLOCK_LENGTH) {
- bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
- }
- /* Do second-to-last transform: */
- SHA512_Transform(context, (uint64_t*)context->buffer);
-
- /* And set-up for the last transform: */
- bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
- }
+ if (usedspace < SHA512_SHORT_BLOCK_LENGTH)
+ {
+ /* Set-up for the last transform: */
+ bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH
+ - usedspace);
+ }
+ else if (usedspace > SHA512_SHORT_BLOCK_LENGTH)
+ {
+ if (usedspace < SHA512_BLOCK_LENGTH)
+ {
+ bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH
+ - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Transform(context, (uint64_t*)context->buffer);
+
+ /* And set-up for the last transform: */
+ bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+ }
#else
- if (usedspace < SHA512_SHORT_BLOCK_LENGTH) {
- /* Set-up for the last transform: */
- bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
- } else {
- if (usedspace < SHA512_BLOCK_LENGTH) {
- bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
- }
- /* Do second-to-last transform: */
- SHA512_Transform(context, (uint64_t*)context->buffer);
-
- /* And set-up for the last transform: */
- bzero(context->buffer, SHA512_BLOCK_LENGTH - 2);
- }
+ if (usedspace < SHA512_SHORT_BLOCK_LENGTH)
+ {
+ /* Set-up for the last transform: */
+ bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH
+ - usedspace);
+ }
+ else
+ {
+ if (usedspace < SHA512_BLOCK_LENGTH)
+ {
+ bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH
+ - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Transform(context, (uint64_t*)context->buffer);
+
+ /* And set-up for the last transform: */
+ bzero(context->buffer, SHA512_BLOCK_LENGTH - 2);
+ }
#endif
- } else {
- /* Prepare for final transform: */
- bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
-
- /* Begin padding with a 1 bit: */
- *context->buffer = 0x80;
- }
- /* Store the length of input data (in bits): */
- *(uint64_t*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
- *(uint64_t*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
-
- /* Final transform: */
- SHA512_Transform(context, (uint64_t*)context->buffer);
+ }
+ else
+ {
+ /* Prepare for final transform: */
+ bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ uint64_t* p1 = reinterpret_cast<uint64_t*>(&context->buffer[SHA512_SHORT_BLOCK_LENGTH]);
+ uint64_t* p2 = reinterpret_cast<uint64_t*>(&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8]);
+ *p1 = context->bitcount[1];
+ *p2 = context->bitcount[0];
+
+ /* Final transform: */
+ SHA512_Transform(context, (uint64_t*)context->buffer);
}
asm(".globl .L.SHA512_Final");
void SHA512_Final(SHA512_CTX* context, sha2_hash_t *result) {
- /* Sanity check: */
- //assert(context != (SHA512_CTX*)0);
+ /* Sanity check: */
+ //assert(context != (SHA512_CTX*)0);
- /* If no digest buffer is passed, we don't bother doing this: */
- SHA512_Last(context);
+ /* If no digest buffer is passed, we don't bother doing this: */
+ SHA512_Last(context);
- /* Save the hash data for output: */
- bcopy(context->state, result, SHA512_DIGEST_LENGTH);
+ /* Save the hash data for output: */
+ bcopy(context->state, result, SHA512_DIGEST_LENGTH);
- /* Zero out state data */
- bzero(context, sizeof(context));
+ /* Zero out state data */
+ bzero(context, sizeof(context));
}
asm(".globl .L.SHA512_Hash");
void SHA512_Hash(const sha2_byte* data, size_t len, sha2_hash_t *result) {
- SHA512_CTX context;
-
- SHA512_Init(&context);
- SHA512_Update(&context, data, len);
- SHA512_Final(&context, result);
-}
-
-/*
-int main( void ){
- int i;
- uint64_t hash[8] = {};
- const sha2_byte text[]={"The quick brown fox jumps over the lazy dog"};
-
- printf("SHA512 \"%s\"\n",text);
- SHA512( text, tstrlen(text), hash );
- for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
- printf("%02x", hash[i]);
- if( (i&3) ==3) printf(" ");
- if( (i&31) ==31) printf("\n");
- }
-
- const sha2_byte text2[]={""};
- printf("SHA512 \"%s\"\n",text2);
- SHA512( text2, tstrlen(text2), hash );
- for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
- printf("%02x", hash[i]);
- if( (i&3) ==3) printf(" ");
- if( (i&31) ==31) printf("\n");
- }
+ SHA512_CTX context;
-}
-*/
-
-#if INCLUDE_SHA_TESTS
-/****************************************************************************/
-static uint8_t SHA512_Input[] = "abc";
-static uint64_t SHA512_Result[] = {
- 0xddaf35a193617abaull, 0xcc417349ae204131ull, 0x12e6fa4e89a97ea2ull, 0x0a9eeee64b55d39aull,
- 0x2192992a274fc1a8ull, 0x36ba3c23a3feebbdull, 0x454d4423643ce80eull, 0x2a9ac94fa54ca49full,
-};
-static uint8_t SHA512_Input2[] =
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
-static uint64_t SHA512_Result2[] = {
- 0x8e959b75dae313daull, 0x8cf4f72814fc143full, 0x8f7779c6eb9f7fa1ull, 0x7299aeadb6889018ull,
- 0x501d289e4900f7e4ull, 0x331b99dec4b5433aull, 0xc7d329eeb6dd2654ull, 0x5e96e55b874be909ull,
-};
-#include <selftest.h>
-/****************************************************************************/
-void SHA512_Test (void)
-{
- SHA512 sha;
- SHA512_Init (&sha);
- SHA512_Update (&sha, SHA512_Input, 3);
- SHA512_Finish (&sha, NULL);
- if (memcmp((uint8_t*)sha.H, (uint8_t*)SHA512_Result, SHA512_DIGEST_SIZE)) {
- printf ("SHA512 Test 1 FAILED with bad digest (\n");
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[0],sha.H[1],sha.H[2],sha.H[3]);
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[4],sha.H[5],sha.H[6],sha.H[7]);
- printf (")\n");
- }
- else {
- printf ("SHA512 Test 1 Complete\n");
- }
- SHA512_Init (&sha);
- SHA512_Update (&sha, SHA512_Input2, 112);
- SHA512_Finish (&sha, NULL);
- if (memcmp((uint8_t*)sha.H, (uint8_t*)SHA512_Result2, SHA512_DIGEST_SIZE)) {
- printf ("SHA512 Test 2 FAILED with bad digest (\n");
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[0],sha.H[1],sha.H[2],sha.H[3]);
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[4],sha.H[5],sha.H[6],sha.H[7]);
- printf (")\n");
- }
- else {
- printf ("SHA512 Test 2 Complete\n");
- }
- SHA512_Hash (&sha, (uint8_t*)&selftest.ec, sizeof(selftest.ec), NULL);
- sha.H[0] = BE2HO_8(sha.H[0]);
- sha.H[1] = BE2HO_8(sha.H[1]);
- sha.H[2] = BE2HO_8(sha.H[2]);
- sha.H[3] = BE2HO_8(sha.H[3]);
- sha.H[4] = BE2HO_8(sha.H[4]);
- sha.H[5] = BE2HO_8(sha.H[5]);
- sha.H[6] = BE2HO_8(sha.H[6]);
- sha.H[7] = BE2HO_8(sha.H[7]);
- if (memcmp((uint8_t*)sha.H, selftest.sha.hash, SHA512_DIGEST_SIZE)) {
- printf ("SHA512 Test 3 FAILED with bad digest (\n");
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[0],sha.H[1],sha.H[2],sha.H[3]);
- printf ("%016llx %016llx %016llx %016llx\n",sha.H[4],sha.H[5],sha.H[6],sha.H[7]);
- printf (")\n");
- }
- else {
- printf ("SHA512 Test 3 Complete\n");
- }
-}
-#endif
+ SHA512_Init(&context);
+ SHA512_Update(&context, data, len);
+ SHA512_Final(&context, result);
+} \ No newline at end of file
OpenPOWER on IntegriCloud