A simple library to support serving https.
Dependents: oldheating gps motorhome heating
sha/sha1.c@6:819c17738dc2, 2019-09-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Sep 01 18:15:12 2019 +0000
- Revision:
- 6:819c17738dc2
- Child:
- 7:94ef5824c3c0
Making progress - now have decryption working.
Who changed what in which revision?
User | Revision | Line number | New 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 | 6:819c17738dc2 | 16 | static void sha1_transform(struct sha1_ctx *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 | 6:819c17738dc2 | 95 | void sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len) |
andrewboyson | 6:819c17738dc2 | 96 | { |
andrewboyson | 6:819c17738dc2 | 97 | int i = ctx->count % sizeof(ctx->buf); |
andrewboyson | 6:819c17738dc2 | 98 | const uint8_t *p = (const uint8_t *)data; |
andrewboyson | 6:819c17738dc2 | 99 | ctx->count += len; |
andrewboyson | 6:819c17738dc2 | 100 | while (len > sizeof(ctx->buf) - i) |
andrewboyson | 6:819c17738dc2 | 101 | { |
andrewboyson | 6:819c17738dc2 | 102 | memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i); |
andrewboyson | 6:819c17738dc2 | 103 | len -= sizeof(ctx->buf) - i; |
andrewboyson | 6:819c17738dc2 | 104 | p += sizeof(ctx->buf) - 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 | 6:819c17738dc2 | 110 | if (i == sizeof(ctx->buf)) { |
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 | 6:819c17738dc2 | 116 | uint8_t *sha1_final(struct sha1_ctx *ctx) |
andrewboyson | 6:819c17738dc2 | 117 | { |
andrewboyson | 6:819c17738dc2 | 118 | uint32_t cnt = ctx->count * 8; |
andrewboyson | 6:819c17738dc2 | 119 | int i; |
andrewboyson | 6:819c17738dc2 | 120 | sha1_update(ctx, (uint8_t *)"\x80", 1); |
andrewboyson | 6:819c17738dc2 | 121 | while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) |
andrewboyson | 6:819c17738dc2 | 122 | sha1_update(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 | 6:819c17738dc2 | 125 | sha1_update(ctx, &tmp, 1); |
andrewboyson | 6:819c17738dc2 | 126 | } |
andrewboyson | 6:819c17738dc2 | 127 | for (i = 0; i < 5; i++) |
andrewboyson | 6:819c17738dc2 | 128 | ctx->buf.w[i] = __builtin_bswap32(ctx->state[i]); |
andrewboyson | 6:819c17738dc2 | 129 | return ctx->buf.b; |
andrewboyson | 6:819c17738dc2 | 130 | } |
andrewboyson | 6:819c17738dc2 | 131 | void sha1_init(struct sha1_ctx *ctx) |
andrewboyson | 6:819c17738dc2 | 132 | { |
andrewboyson | 6:819c17738dc2 | 133 | ctx->state[0] = 0x67452301; |
andrewboyson | 6:819c17738dc2 | 134 | ctx->state[1] = 0xEFCDAB89; |
andrewboyson | 6:819c17738dc2 | 135 | ctx->state[2] = 0x98BADCFE; |
andrewboyson | 6:819c17738dc2 | 136 | ctx->state[3] = 0x10325476; |
andrewboyson | 6:819c17738dc2 | 137 | ctx->state[4] = 0xC3D2E1F0; |
andrewboyson | 6:819c17738dc2 | 138 | ctx->count = 0; |
andrewboyson | 6:819c17738dc2 | 139 | } |