A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Oct 02 20:26:04 2019 +0000
Revision:
14:03a0b8fd6ddc
Parent:
12:2c342345b3db
Session resume now working. TLS working quickly after the initial 5 second RSA decrypt time using the 1024 bit private key.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 14:03a0b8fd6ddc 1 #include <stdint.h>
andrewboyson 14:03a0b8fd6ddc 2 #include <stdbool.h>
andrewboyson 12:2c342345b3db 3 #include "rsa.h"
andrewboyson 14:03a0b8fd6ddc 4 #include "bignum.h"
andrewboyson 14:03a0b8fd6ddc 5 #include "hrtimer.h"
andrewboyson 14:03a0b8fd6ddc 6 #include "log.h"
andrewboyson 14:03a0b8fd6ddc 7
andrewboyson 14:03a0b8fd6ddc 8 typedef enum status_e
andrewboyson 14:03a0b8fd6ddc 9 {
andrewboyson 14:03a0b8fd6ddc 10 STATUS_NONE,
andrewboyson 14:03a0b8fd6ddc 11 STATUS_FINISHED,
andrewboyson 14:03a0b8fd6ddc 12 STATUS_STARTED,
andrewboyson 14:03a0b8fd6ddc 13 STATUS_CALCULATE_M1,
andrewboyson 14:03a0b8fd6ddc 14 STATUS_CALCULATE_M2,
andrewboyson 14:03a0b8fd6ddc 15 STATUS_CALCULATE_HBIS,
andrewboyson 14:03a0b8fd6ddc 16 STATUS_CALCULATE_H,
andrewboyson 14:03a0b8fd6ddc 17 STATUS_CALCULATE_R
andrewboyson 14:03a0b8fd6ddc 18 } status_t;
andrewboyson 14:03a0b8fd6ddc 19
andrewboyson 14:03a0b8fd6ddc 20 typedef struct slot_s
andrewboyson 14:03a0b8fd6ddc 21 {
andrewboyson 14:03a0b8fd6ddc 22 uint32_t m1[16];
andrewboyson 14:03a0b8fd6ddc 23 uint32_t m2[16];
andrewboyson 14:03a0b8fd6ddc 24 uint32_t n1[16];
andrewboyson 14:03a0b8fd6ddc 25 uint32_t n2[16];
andrewboyson 14:03a0b8fd6ddc 26 uint32_t e1[16];
andrewboyson 14:03a0b8fd6ddc 27 uint32_t e2[16];
andrewboyson 14:03a0b8fd6ddc 28 uint32_t r1[16];
andrewboyson 14:03a0b8fd6ddc 29 uint32_t r2[16];
andrewboyson 14:03a0b8fd6ddc 30 uint32_t qi[16];
andrewboyson 14:03a0b8fd6ddc 31 uint32_t r[32];
andrewboyson 14:03a0b8fd6ddc 32 status_t status;
andrewboyson 14:03a0b8fd6ddc 33 } slot_t;
andrewboyson 14:03a0b8fd6ddc 34 #define MAX_COUNT 4
andrewboyson 14:03a0b8fd6ddc 35 static slot_t slots[MAX_COUNT];
andrewboyson 14:03a0b8fd6ddc 36
andrewboyson 14:03a0b8fd6ddc 37 static uint32_t hbis[32];
andrewboyson 14:03a0b8fd6ddc 38 static uint32_t h[16];
andrewboyson 14:03a0b8fd6ddc 39
andrewboyson 12:2c342345b3db 40
andrewboyson 14:03a0b8fd6ddc 41 void start(slot_t* pSlot, uint32_t* message, uint32_t* p, uint32_t* q, uint32_t* dp, uint32_t* dq, uint32_t* qInv)
andrewboyson 14:03a0b8fd6ddc 42 {
andrewboyson 14:03a0b8fd6ddc 43 BnModExpStart512(pSlot->m1, pSlot->e1, pSlot->n1, pSlot->r1, 1024, message, dp, p);
andrewboyson 14:03a0b8fd6ddc 44 BnModExpStart512(pSlot->m2, pSlot->e2, pSlot->n2, pSlot->r2, 1024, message, dq, q);
andrewboyson 14:03a0b8fd6ddc 45 BnCpy512(pSlot->qi, qInv);
andrewboyson 14:03a0b8fd6ddc 46 pSlot->status = STATUS_STARTED;
andrewboyson 14:03a0b8fd6ddc 47 }
andrewboyson 14:03a0b8fd6ddc 48 void iterate(slot_t* pSlot)
andrewboyson 12:2c342345b3db 49 {
andrewboyson 14:03a0b8fd6ddc 50 /*
andrewboyson 14:03a0b8fd6ddc 51 m1 = c^dP mod p
andrewboyson 14:03a0b8fd6ddc 52 m2 = c^dQ mod q
andrewboyson 14:03a0b8fd6ddc 53 h = qInv.(m1 - m2) mod p
andrewboyson 14:03a0b8fd6ddc 54 m = m2 + h.q
andrewboyson 14:03a0b8fd6ddc 55 */
andrewboyson 14:03a0b8fd6ddc 56
andrewboyson 14:03a0b8fd6ddc 57 switch (pSlot->status)
andrewboyson 14:03a0b8fd6ddc 58 {
andrewboyson 14:03a0b8fd6ddc 59 case STATUS_NONE:
andrewboyson 14:03a0b8fd6ddc 60 case STATUS_FINISHED:
andrewboyson 14:03a0b8fd6ddc 61 {
andrewboyson 14:03a0b8fd6ddc 62 break;
andrewboyson 14:03a0b8fd6ddc 63 }
andrewboyson 14:03a0b8fd6ddc 64 case STATUS_STARTED:
andrewboyson 14:03a0b8fd6ddc 65 {
andrewboyson 14:03a0b8fd6ddc 66 pSlot->status = STATUS_CALCULATE_M1;
andrewboyson 14:03a0b8fd6ddc 67 break;
andrewboyson 14:03a0b8fd6ddc 68 }
andrewboyson 14:03a0b8fd6ddc 69 case STATUS_CALCULATE_M1:
andrewboyson 14:03a0b8fd6ddc 70 {
andrewboyson 14:03a0b8fd6ddc 71 bool finished = BnModExpIterate512(pSlot->m1, pSlot->e1, pSlot->n1, pSlot->r1);
andrewboyson 14:03a0b8fd6ddc 72 if (finished) pSlot->status = STATUS_CALCULATE_M2;
andrewboyson 14:03a0b8fd6ddc 73 break;
andrewboyson 14:03a0b8fd6ddc 74 }
andrewboyson 14:03a0b8fd6ddc 75 case STATUS_CALCULATE_M2:
andrewboyson 14:03a0b8fd6ddc 76 {
andrewboyson 14:03a0b8fd6ddc 77 bool finished = BnModExpIterate512(pSlot->m2, pSlot->e2, pSlot->n2, pSlot->r2);
andrewboyson 14:03a0b8fd6ddc 78 if (finished) pSlot->status = STATUS_CALCULATE_HBIS;
andrewboyson 14:03a0b8fd6ddc 79 break;
andrewboyson 14:03a0b8fd6ddc 80 }
andrewboyson 14:03a0b8fd6ddc 81 case STATUS_CALCULATE_HBIS:
andrewboyson 14:03a0b8fd6ddc 82 {
andrewboyson 14:03a0b8fd6ddc 83 uint32_t acc512[16];
andrewboyson 14:03a0b8fd6ddc 84 BnCpy512(acc512, pSlot->r1);
andrewboyson 14:03a0b8fd6ddc 85 if (BnCmp512(pSlot->r1, pSlot->r2) < 0) BnAdd512(acc512, pSlot->n1); // if m1 < m2 add p to keep positive
andrewboyson 14:03a0b8fd6ddc 86 BnSub512(acc512, pSlot->r2);
andrewboyson 14:03a0b8fd6ddc 87 Bn512Mul1024(pSlot->qi, acc512, hbis);
andrewboyson 14:03a0b8fd6ddc 88 pSlot->status = STATUS_CALCULATE_H;
andrewboyson 14:03a0b8fd6ddc 89 break;
andrewboyson 14:03a0b8fd6ddc 90 }
andrewboyson 14:03a0b8fd6ddc 91 case STATUS_CALCULATE_H:
andrewboyson 14:03a0b8fd6ddc 92 {
andrewboyson 14:03a0b8fd6ddc 93 BnRem512(1024, hbis, pSlot->n1, h);
andrewboyson 14:03a0b8fd6ddc 94 pSlot->status = STATUS_CALCULATE_R;
andrewboyson 14:03a0b8fd6ddc 95 break;
andrewboyson 14:03a0b8fd6ddc 96 }
andrewboyson 14:03a0b8fd6ddc 97 case STATUS_CALCULATE_R:
andrewboyson 14:03a0b8fd6ddc 98 {
andrewboyson 14:03a0b8fd6ddc 99 uint32_t hq1024[32];
andrewboyson 14:03a0b8fd6ddc 100 Bn512Mul1024(h, pSlot->n2, hq1024);
andrewboyson 14:03a0b8fd6ddc 101 BnZer1024(pSlot->r);
andrewboyson 14:03a0b8fd6ddc 102 BnCpy512(pSlot->r, pSlot->r2);
andrewboyson 14:03a0b8fd6ddc 103 BnAdd1024(pSlot->r, hq1024);
andrewboyson 14:03a0b8fd6ddc 104 pSlot->status = STATUS_FINISHED;
andrewboyson 14:03a0b8fd6ddc 105 break;
andrewboyson 14:03a0b8fd6ddc 106 }
andrewboyson 14:03a0b8fd6ddc 107 }
andrewboyson 12:2c342345b3db 108 }
andrewboyson 12:2c342345b3db 109
andrewboyson 14:03a0b8fd6ddc 110 bool RsaFinished(int slotIndex)
andrewboyson 14:03a0b8fd6ddc 111 {
andrewboyson 14:03a0b8fd6ddc 112 return slots[slotIndex].status == STATUS_FINISHED;
andrewboyson 14:03a0b8fd6ddc 113 }
andrewboyson 14:03a0b8fd6ddc 114 uint32_t* RsaResult(int slotIndex)
andrewboyson 14:03a0b8fd6ddc 115 {
andrewboyson 14:03a0b8fd6ddc 116 return slots[slotIndex].r;
andrewboyson 14:03a0b8fd6ddc 117 }
andrewboyson 14:03a0b8fd6ddc 118 void RsaClear(int slotIndex) //This is for security - call it as soon as you no longer need the result.
andrewboyson 14:03a0b8fd6ddc 119 {
andrewboyson 14:03a0b8fd6ddc 120 slot_t* pSlot = slots + slotIndex;
andrewboyson 14:03a0b8fd6ddc 121 pSlot->status = STATUS_NONE;
andrewboyson 14:03a0b8fd6ddc 122 BnZer512 (pSlot->m1);
andrewboyson 14:03a0b8fd6ddc 123 BnZer512 (pSlot->m2);
andrewboyson 14:03a0b8fd6ddc 124 BnZer512 (pSlot->e1);
andrewboyson 14:03a0b8fd6ddc 125 BnZer512 (pSlot->e2);
andrewboyson 14:03a0b8fd6ddc 126 BnZer512 (pSlot->n1);
andrewboyson 14:03a0b8fd6ddc 127 BnZer512 (pSlot->n2);
andrewboyson 14:03a0b8fd6ddc 128 BnZer512 (pSlot->r1);
andrewboyson 14:03a0b8fd6ddc 129 BnZer512 (pSlot->r2);
andrewboyson 14:03a0b8fd6ddc 130 BnZer512 (pSlot->qi);
andrewboyson 14:03a0b8fd6ddc 131 BnZer1024(pSlot->r);
andrewboyson 14:03a0b8fd6ddc 132 }
andrewboyson 14:03a0b8fd6ddc 133 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!
andrewboyson 14:03a0b8fd6ddc 134 {
andrewboyson 14:03a0b8fd6ddc 135 //If the exponent is empty then bomb out
andrewboyson 14:03a0b8fd6ddc 136 if (BnIse1024(dp))
andrewboyson 14:03a0b8fd6ddc 137 {
andrewboyson 14:03a0b8fd6ddc 138 LogTime("Fast - empty dp\r\n");
andrewboyson 14:03a0b8fd6ddc 139 return -1;
andrewboyson 14:03a0b8fd6ddc 140 }
andrewboyson 14:03a0b8fd6ddc 141 if (BnIse1024(dq))
andrewboyson 14:03a0b8fd6ddc 142 {
andrewboyson 14:03a0b8fd6ddc 143 LogTime("Fast - empty dq\r\n");
andrewboyson 14:03a0b8fd6ddc 144 return -1;
andrewboyson 14:03a0b8fd6ddc 145 }
andrewboyson 14:03a0b8fd6ddc 146
andrewboyson 14:03a0b8fd6ddc 147 //Look for an empty slot
andrewboyson 14:03a0b8fd6ddc 148 for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++)
andrewboyson 14:03a0b8fd6ddc 149 {
andrewboyson 14:03a0b8fd6ddc 150 if (pSlot->status == STATUS_NONE)
andrewboyson 14:03a0b8fd6ddc 151 {
andrewboyson 14:03a0b8fd6ddc 152 start(pSlot, message, p, q, dp, dq, qInv);
andrewboyson 14:03a0b8fd6ddc 153 return pSlot - slots;
andrewboyson 14:03a0b8fd6ddc 154 }
andrewboyson 14:03a0b8fd6ddc 155 }
andrewboyson 14:03a0b8fd6ddc 156
andrewboyson 14:03a0b8fd6ddc 157 //Look for a slot whch has been used and not cleared
andrewboyson 14:03a0b8fd6ddc 158 for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++)
andrewboyson 14:03a0b8fd6ddc 159 {
andrewboyson 14:03a0b8fd6ddc 160 if (pSlot->status == STATUS_FINISHED)
andrewboyson 14:03a0b8fd6ddc 161 {
andrewboyson 14:03a0b8fd6ddc 162 start(pSlot, message, p, q, dp, dq, qInv);
andrewboyson 14:03a0b8fd6ddc 163 return pSlot - slots;
andrewboyson 14:03a0b8fd6ddc 164 }
andrewboyson 14:03a0b8fd6ddc 165 }
andrewboyson 14:03a0b8fd6ddc 166
andrewboyson 14:03a0b8fd6ddc 167 //No available slot so bomb out
andrewboyson 14:03a0b8fd6ddc 168 LogTimeF("RsaFastStart - no available slots out of %d\r\n", MAX_COUNT);
andrewboyson 14:03a0b8fd6ddc 169 return -1;
andrewboyson 14:03a0b8fd6ddc 170
andrewboyson 14:03a0b8fd6ddc 171 }
andrewboyson 12:2c342345b3db 172 void RsaMain()
andrewboyson 12:2c342345b3db 173 {
andrewboyson 14:03a0b8fd6ddc 174 //Always complete existing calculations first
andrewboyson 14:03a0b8fd6ddc 175 slot_t* pHighestSlot = 0;
andrewboyson 14:03a0b8fd6ddc 176 int highestStatus = STATUS_FINISHED;
andrewboyson 14:03a0b8fd6ddc 177
andrewboyson 14:03a0b8fd6ddc 178 for (slot_t* pSlot = slots; pSlot < slots + MAX_COUNT; pSlot++)
andrewboyson 14:03a0b8fd6ddc 179 {
andrewboyson 14:03a0b8fd6ddc 180 if (pSlot->status > highestStatus)
andrewboyson 14:03a0b8fd6ddc 181 {
andrewboyson 14:03a0b8fd6ddc 182 highestStatus = pSlot->status;
andrewboyson 14:03a0b8fd6ddc 183 pHighestSlot = pSlot;
andrewboyson 14:03a0b8fd6ddc 184 }
andrewboyson 14:03a0b8fd6ddc 185 }
andrewboyson 14:03a0b8fd6ddc 186 if (highestStatus > STATUS_FINISHED) iterate(pHighestSlot);
andrewboyson 14:03a0b8fd6ddc 187 }
andrewboyson 14:03a0b8fd6ddc 188
andrewboyson 14:03a0b8fd6ddc 189 void RsaInit(void)
andrewboyson 14:03a0b8fd6ddc 190 {
andrewboyson 14:03a0b8fd6ddc 191 for (int i = 0; i < MAX_COUNT; i++) slots[i].status = STATUS_NONE;
andrewboyson 12:2c342345b3db 192 }