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 6:819c17738dc2 1 #include <string.h>
andrewboyson 6:819c17738dc2 2 #include "sha1.h"
andrewboyson 6:819c17738dc2 3
andrewboyson 6:819c17738dc2 4 static uint32_t ror27(uint32_t val)
andrewboyson 6:819c17738dc2 5 {
andrewboyson 6:819c17738dc2 6 return (val >> 27) | (val << 5);
andrewboyson 6:819c17738dc2 7 }
andrewboyson 6:819c17738dc2 8 static uint32_t ror2(uint32_t val)
andrewboyson 6:819c17738dc2 9 {
andrewboyson 6:819c17738dc2 10 return (val >> 2) | (val << 30);
andrewboyson 6:819c17738dc2 11 }
andrewboyson 6:819c17738dc2 12 static uint32_t ror31(uint32_t val)
andrewboyson 6:819c17738dc2 13 {
andrewboyson 6:819c17738dc2 14 return (val >> 31) | (val << 1);
andrewboyson 6:819c17738dc2 15 }
andrewboyson 7:94ef5824c3c0 16 static void sha1_transform(struct Sha1State *ctx)
andrewboyson 6:819c17738dc2 17 {
andrewboyson 6:819c17738dc2 18 uint32_t W[80];
andrewboyson 6:819c17738dc2 19 register uint32_t A, B, C, D, E;
andrewboyson 6:819c17738dc2 20 int t;
andrewboyson 6:819c17738dc2 21 A = ctx->state[0];
andrewboyson 6:819c17738dc2 22 B = ctx->state[1];
andrewboyson 6:819c17738dc2 23 C = ctx->state[2];
andrewboyson 6:819c17738dc2 24 D = ctx->state[3];
andrewboyson 6:819c17738dc2 25 E = ctx->state[4];
andrewboyson 6:819c17738dc2 26 #define SHA_F1(A, B, C, D, E, t) \
andrewboyson 6:819c17738dc2 27 E += ror27(A) + \
andrewboyson 6:819c17738dc2 28 (W[t] = __builtin_bswap32(ctx->buf.w[t])) + \
andrewboyson 6:819c17738dc2 29 (D^(B&(C^D))) + 0x5A827999; \
andrewboyson 6:819c17738dc2 30 B = ror2(B);
andrewboyson 6:819c17738dc2 31 for (t = 0; t < 15; t += 5) {
andrewboyson 6:819c17738dc2 32 SHA_F1(A, B, C, D, E, t + 0);
andrewboyson 6:819c17738dc2 33 SHA_F1(E, A, B, C, D, t + 1);
andrewboyson 6:819c17738dc2 34 SHA_F1(D, E, A, B, C, t + 2);
andrewboyson 6:819c17738dc2 35 SHA_F1(C, D, E, A, B, t + 3);
andrewboyson 6:819c17738dc2 36 SHA_F1(B, C, D, E, A, t + 4);
andrewboyson 6:819c17738dc2 37 }
andrewboyson 6:819c17738dc2 38 SHA_F1(A, B, C, D, E, t + 0); /* 16th one, t == 15 */
andrewboyson 6:819c17738dc2 39 #undef SHA_F1
andrewboyson 6:819c17738dc2 40 #define SHA_F1(A, B, C, D, E, t) \
andrewboyson 6:819c17738dc2 41 E += ror27(A) + \
andrewboyson 6:819c17738dc2 42 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
andrewboyson 6:819c17738dc2 43 (D^(B&(C^D))) + 0x5A827999; \
andrewboyson 6:819c17738dc2 44 B = ror2(B);
andrewboyson 6:819c17738dc2 45 SHA_F1(E, A, B, C, D, t + 1);
andrewboyson 6:819c17738dc2 46 SHA_F1(D, E, A, B, C, t + 2);
andrewboyson 6:819c17738dc2 47 SHA_F1(C, D, E, A, B, t + 3);
andrewboyson 6:819c17738dc2 48 SHA_F1(B, C, D, E, A, t + 4);
andrewboyson 6:819c17738dc2 49 #undef SHA_F1
andrewboyson 6:819c17738dc2 50 #define SHA_F2(A, B, C, D, E, t) \
andrewboyson 6:819c17738dc2 51 E += ror27(A) + \
andrewboyson 6:819c17738dc2 52 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
andrewboyson 6:819c17738dc2 53 (B^C^D) + 0x6ED9EBA1; \
andrewboyson 6:819c17738dc2 54 B = ror2(B);
andrewboyson 6:819c17738dc2 55 for (t = 20; t < 40; t += 5) {
andrewboyson 6:819c17738dc2 56 SHA_F2(A, B, C, D, E, t + 0);
andrewboyson 6:819c17738dc2 57 SHA_F2(E, A, B, C, D, t + 1);
andrewboyson 6:819c17738dc2 58 SHA_F2(D, E, A, B, C, t + 2);
andrewboyson 6:819c17738dc2 59 SHA_F2(C, D, E, A, B, t + 3);
andrewboyson 6:819c17738dc2 60 SHA_F2(B, C, D, E, A, t + 4);
andrewboyson 6:819c17738dc2 61 }
andrewboyson 6:819c17738dc2 62 #undef SHA_F2
andrewboyson 6:819c17738dc2 63 #define SHA_F3(A, B, C, D, E, t) \
andrewboyson 6:819c17738dc2 64 E += ror27(A) + \
andrewboyson 6:819c17738dc2 65 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
andrewboyson 6:819c17738dc2 66 ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \
andrewboyson 6:819c17738dc2 67 B = ror2(B);
andrewboyson 6:819c17738dc2 68 for (; t < 60; t += 5) {
andrewboyson 6:819c17738dc2 69 SHA_F3(A, B, C, D, E, t + 0);
andrewboyson 6:819c17738dc2 70 SHA_F3(E, A, B, C, D, t + 1);
andrewboyson 6:819c17738dc2 71 SHA_F3(D, E, A, B, C, t + 2);
andrewboyson 6:819c17738dc2 72 SHA_F3(C, D, E, A, B, t + 3);
andrewboyson 6:819c17738dc2 73 SHA_F3(B, C, D, E, A, t + 4);
andrewboyson 6:819c17738dc2 74 }
andrewboyson 6:819c17738dc2 75 #undef SHA_F3
andrewboyson 6:819c17738dc2 76 #define SHA_F4(A, B, C, D, E, t) \
andrewboyson 6:819c17738dc2 77 E += ror27(A) + \
andrewboyson 6:819c17738dc2 78 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
andrewboyson 6:819c17738dc2 79 (B^C^D) + 0xCA62C1D6; \
andrewboyson 6:819c17738dc2 80 B = ror2(B);
andrewboyson 6:819c17738dc2 81 for (; t < 80; t += 5) {
andrewboyson 6:819c17738dc2 82 SHA_F4(A, B, C, D, E, t + 0);
andrewboyson 6:819c17738dc2 83 SHA_F4(E, A, B, C, D, t + 1);
andrewboyson 6:819c17738dc2 84 SHA_F4(D, E, A, B, C, t + 2);
andrewboyson 6:819c17738dc2 85 SHA_F4(C, D, E, A, B, t + 3);
andrewboyson 6:819c17738dc2 86 SHA_F4(B, C, D, E, A, t + 4);
andrewboyson 6:819c17738dc2 87 }
andrewboyson 6:819c17738dc2 88 #undef SHA_F4
andrewboyson 6:819c17738dc2 89 ctx->state[0] += A;
andrewboyson 6:819c17738dc2 90 ctx->state[1] += B;
andrewboyson 6:819c17738dc2 91 ctx->state[2] += C;
andrewboyson 6:819c17738dc2 92 ctx->state[3] += D;
andrewboyson 6:819c17738dc2 93 ctx->state[4] += E;
andrewboyson 6:819c17738dc2 94 }
andrewboyson 7:94ef5824c3c0 95 void Sha1Add(struct Sha1State *ctx, const uint8_t *data, int len)
andrewboyson 6:819c17738dc2 96 {
andrewboyson 14:03a0b8fd6ddc 97 int i = ctx->count % SHA1_BLOCK_SIZE;
andrewboyson 6:819c17738dc2 98 const uint8_t *p = (const uint8_t *)data;
andrewboyson 6:819c17738dc2 99 ctx->count += len;
andrewboyson 14:03a0b8fd6ddc 100 while (len > SHA1_BLOCK_SIZE - i)
andrewboyson 6:819c17738dc2 101 {
andrewboyson 14:03a0b8fd6ddc 102 memcpy(&ctx->buf.b[i], p, SHA1_BLOCK_SIZE - i);
andrewboyson 14:03a0b8fd6ddc 103 len -= SHA1_BLOCK_SIZE - i;
andrewboyson 14:03a0b8fd6ddc 104 p += SHA1_BLOCK_SIZE - i;
andrewboyson 6:819c17738dc2 105 sha1_transform(ctx);
andrewboyson 6:819c17738dc2 106 i = 0;
andrewboyson 6:819c17738dc2 107 }
andrewboyson 6:819c17738dc2 108 while (len--) {
andrewboyson 6:819c17738dc2 109 ctx->buf.b[i++] = *p++;
andrewboyson 14:03a0b8fd6ddc 110 if (i == SHA1_BLOCK_SIZE) {
andrewboyson 6:819c17738dc2 111 sha1_transform(ctx);
andrewboyson 6:819c17738dc2 112 i = 0;
andrewboyson 6:819c17738dc2 113 }
andrewboyson 6:819c17738dc2 114 }
andrewboyson 6:819c17738dc2 115 }
andrewboyson 7:94ef5824c3c0 116 void Sha1Finish(struct Sha1State *ctx, uint8_t *out)
andrewboyson 6:819c17738dc2 117 {
andrewboyson 6:819c17738dc2 118 uint32_t cnt = ctx->count * 8;
andrewboyson 6:819c17738dc2 119 int i;
andrewboyson 7:94ef5824c3c0 120 Sha1Add(ctx, (uint8_t *)"\x80", 1);
andrewboyson 14:03a0b8fd6ddc 121 while ((ctx->count % SHA1_BLOCK_SIZE) != (SHA1_BLOCK_SIZE - 8))
andrewboyson 7:94ef5824c3c0 122 Sha1Add(ctx, (uint8_t *)"\0", 1);
andrewboyson 6:819c17738dc2 123 for (i = 0; i < 8; ++i) {
andrewboyson 6:819c17738dc2 124 uint8_t tmp = cnt >> ((7 - i) * 8);
andrewboyson 7:94ef5824c3c0 125 Sha1Add(ctx, &tmp, 1);
andrewboyson 6:819c17738dc2 126 }
andrewboyson 7:94ef5824c3c0 127 for (i = 0; i < 5; i++) ctx->buf.w[i] = __builtin_bswap32(ctx->state[i]);
andrewboyson 7:94ef5824c3c0 128 for (i = 0; i < 20; i++) out[i] = ctx->buf.b[i];
andrewboyson 6:819c17738dc2 129 }
andrewboyson 7:94ef5824c3c0 130 void Sha1Start(struct Sha1State *ctx)
andrewboyson 6:819c17738dc2 131 {
andrewboyson 6:819c17738dc2 132 ctx->state[0] = 0x67452301;
andrewboyson 6:819c17738dc2 133 ctx->state[1] = 0xEFCDAB89;
andrewboyson 6:819c17738dc2 134 ctx->state[2] = 0x98BADCFE;
andrewboyson 6:819c17738dc2 135 ctx->state[3] = 0x10325476;
andrewboyson 6:819c17738dc2 136 ctx->state[4] = 0xC3D2E1F0;
andrewboyson 6:819c17738dc2 137 ctx->count = 0;
andrewboyson 7:94ef5824c3c0 138 }
andrewboyson 7:94ef5824c3c0 139
andrewboyson 7:94ef5824c3c0 140 void Sha1(const uint8_t* in, int inlen, uint8_t* hash)
andrewboyson 7:94ef5824c3c0 141 {
andrewboyson 7:94ef5824c3c0 142 struct Sha1State md;
andrewboyson 7:94ef5824c3c0 143 Sha1Start (&md);
andrewboyson 7:94ef5824c3c0 144 Sha1Add (&md, in, inlen);
andrewboyson 7:94ef5824c3c0 145 Sha1Finish(&md, hash);
andrewboyson 6:819c17738dc2 146 }