A simple library to support serving https.
Dependents: oldheating gps motorhome heating
rsa/rsa.c
- Committer:
- andrewboyson
- Date:
- 2019-10-02
- Revision:
- 14:03a0b8fd6ddc
- Parent:
- 12:2c342345b3db
File content as of revision 14:03a0b8fd6ddc:
#include <stdint.h> #include <stdbool.h> #include "rsa.h" #include "bignum.h" #include "hrtimer.h" #include "log.h" typedef enum status_e { STATUS_NONE, STATUS_FINISHED, STATUS_STARTED, STATUS_CALCULATE_M1, STATUS_CALCULATE_M2, STATUS_CALCULATE_HBIS, STATUS_CALCULATE_H, STATUS_CALCULATE_R } status_t; typedef struct slot_s { uint32_t m1[16]; uint32_t m2[16]; uint32_t n1[16]; uint32_t n2[16]; uint32_t e1[16]; uint32_t e2[16]; uint32_t r1[16]; uint32_t r2[16]; uint32_t qi[16]; uint32_t r[32]; status_t status; } slot_t; #define MAX_COUNT 4 static slot_t slots[MAX_COUNT]; static uint32_t hbis[32]; static uint32_t h[16]; void start(slot_t* pSlot, uint32_t* message, uint32_t* p, uint32_t* q, uint32_t* dp, uint32_t* dq, uint32_t* qInv) { BnModExpStart512(pSlot->m1, pSlot->e1, pSlot->n1, pSlot->r1, 1024, message, dp, p); BnModExpStart512(pSlot->m2, pSlot->e2, pSlot->n2, pSlot->r2, 1024, message, dq, q); BnCpy512(pSlot->qi, qInv); pSlot->status = STATUS_STARTED; } void iterate(slot_t* pSlot) { /* m1 = c^dP mod p m2 = c^dQ mod q h = qInv.(m1 - m2) mod p m = m2 + h.q */ switch (pSlot->status) { case STATUS_NONE: case STATUS_FINISHED: { break; } case STATUS_STARTED: { pSlot->status = STATUS_CALCULATE_M1; break; } case STATUS_CALCULATE_M1: { bool finished = BnModExpIterate512(pSlot->m1, pSlot->e1, pSlot->n1, pSlot->r1); if (finished) pSlot->status = STATUS_CALCULATE_M2; break; } case STATUS_CALCULATE_M2: { bool finished = BnModExpIterate512(pSlot->m2, pSlot->e2, pSlot->n2, pSlot->r2); if (finished) pSlot->status = STATUS_CALCULATE_HBIS; break; } case STATUS_CALCULATE_HBIS: { uint32_t acc512[16]; BnCpy512(acc512, pSlot->r1); if (BnCmp512(pSlot->r1, pSlot->r2) < 0) BnAdd512(acc512, pSlot->n1); // if m1 < m2 add p to keep positive BnSub512(acc512, pSlot->r2); Bn512Mul1024(pSlot->qi, acc512, hbis); pSlot->status = STATUS_CALCULATE_H; break; } case STATUS_CALCULATE_H: { BnRem512(1024, hbis, pSlot->n1, h); pSlot->status = STATUS_CALCULATE_R; break; } case STATUS_CALCULATE_R: { uint32_t hq1024[32]; Bn512Mul1024(h, pSlot->n2, hq1024); BnZer1024(pSlot->r); BnCpy512(pSlot->r, pSlot->r2); BnAdd1024(pSlot->r, hq1024); pSlot->status = STATUS_FINISHED; break; } } } bool RsaFinished(int slotIndex) { return slots[slotIndex].status == STATUS_FINISHED; } uint32_t* RsaResult(int slotIndex) { return slots[slotIndex].r; } void RsaClear(int slotIndex) //This is for security - call it as soon as you no longer need the result. { slot_t* pSlot = slots + slotIndex; pSlot->status = STATUS_NONE; BnZer512 (pSlot->m1); BnZer512 (pSlot->m2); BnZer512 (pSlot->e1); BnZer512 (pSlot->e2); BnZer512 (pSlot->n1); BnZer512 (pSlot->n2); BnZer512 (pSlot->r1); BnZer512 (pSlot->r2); BnZer512 (pSlot->qi); BnZer1024(pSlot->r); } int RsaStart(uint32_t* message, uint32_t* p, uint32_t* q, uint32_t* dp, uint32_t* dq, uint32_t* qInv) //Returns the slot or -1 on failure - you must check! { //If the exponent is empty then bomb out if (BnIse1024(dp)) { LogTime("Fast - empty dp\r\n"); return -1; } if (BnIse1024(dq)) { LogTime("Fast - empty dq\r\n"); return -1; } //Look for an empty slot for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++) { if (pSlot->status == STATUS_NONE) { start(pSlot, message, p, q, dp, dq, qInv); return pSlot - slots; } } //Look for a slot whch has been used and not cleared for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++) { if (pSlot->status == STATUS_FINISHED) { start(pSlot, message, p, q, dp, dq, qInv); return pSlot - slots; } } //No available slot so bomb out LogTimeF("RsaFastStart - no available slots out of %d\r\n", MAX_COUNT); return -1; } void RsaMain() { //Always complete existing calculations first slot_t* pHighestSlot = 0; int highestStatus = STATUS_FINISHED; for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++) { if (pSlot->status > highestStatus) { highestStatus = pSlot->status; pHighestSlot = pSlot; } } if (highestStatus > STATUS_FINISHED) iterate(pHighestSlot); } void RsaInit(void) { for (int i = 0; i < MAX_COUNT; i++) slots[i].status = STATUS_NONE; }