A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Apr 01 12:48:52 2020 +0000
Revision:
24:cb43290fc439
Parent:
14:03a0b8fd6ddc
Added check so that if the client closes the TCP connection before the TLS connection is established then respond that we have finished and the TCP connection is to be closed.

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 }