summaryrefslogtreecommitdiffstats
path: root/src/securerom
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 /src/securerom
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>
Diffstat (limited to 'src/securerom')
-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
7 files changed, 1651 insertions, 2276 deletions
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