A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Revision:
14:03a0b8fd6ddc
Parent:
12:2c342345b3db
--- a/rsa/rsa.c	Fri Sep 27 11:31:18 2019 +0000
+++ b/rsa/rsa.c	Wed Oct 02 20:26:04 2019 +0000
@@ -1,13 +1,192 @@
+#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 RsaInit()
+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)
 {
-    RsaSlowInit();
-    RsaFastInit();
+    /*
+    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()
 {
-    RsaSlowMain();
-    RsaFastMain();
+    //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;
 }
\ No newline at end of file