A simple library to support serving https.
Dependents: oldheating gps motorhome heating
rsa/rsa.c@24:cb43290fc439, 2020-04-01 (annotated)
- 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?
User | Revision | Line number | New 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 | } |