A simple library to support serving https.
Dependents: oldheating gps motorhome heating
rsa/rsa.c@14:03a0b8fd6ddc, 2019-10-02 (annotated)
- 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?
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 | } |