A simple library to support serving https.
Dependents: oldheating gps motorhome heating
pki/pri-key.c@14:03a0b8fd6ddc, 2019-10-02 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Oct 02 20:26:04 2019 +0000
- Revision:
- 14:03a0b8fd6ddc
- Parent:
- 12:2c342345b3db
- Child:
- 17:93feb2a51d58
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 | 4:6a1d887f1cad | 1 | #include <stdint.h> |
andrewboyson | 4:6a1d887f1cad | 2 | |
andrewboyson | 0:be515c9019e3 | 3 | #include "base64.h" |
andrewboyson | 0:be515c9019e3 | 4 | #include "log.h" |
andrewboyson | 10:e269fd7b9500 | 5 | #include "rsa.h" |
andrewboyson | 0:be515c9019e3 | 6 | |
andrewboyson | 0:be515c9019e3 | 7 | /* |
andrewboyson | 0:be515c9019e3 | 8 | RSAPrivateKey ::= SEQUENCE { |
andrewboyson | 0:be515c9019e3 | 9 | version INTEGER, |
andrewboyson | 0:be515c9019e3 | 10 | modulus INTEGER, -- n |
andrewboyson | 0:be515c9019e3 | 11 | publicExponent INTEGER, -- e |
andrewboyson | 0:be515c9019e3 | 12 | privateExponent INTEGER, -- d |
andrewboyson | 0:be515c9019e3 | 13 | prime1 INTEGER, -- p |
andrewboyson | 0:be515c9019e3 | 14 | prime2 INTEGER, -- q |
andrewboyson | 0:be515c9019e3 | 15 | exponent1 INTEGER, -- d mod (p-1) |
andrewboyson | 0:be515c9019e3 | 16 | exponent2 INTEGER, -- d mod (q-1) |
andrewboyson | 0:be515c9019e3 | 17 | coefficient INTEGER, -- (inverse of q) mod p |
andrewboyson | 0:be515c9019e3 | 18 | otherPrimeInfos OtherPrimeInfos OPTIONAL |
andrewboyson | 0:be515c9019e3 | 19 | */ |
andrewboyson | 0:be515c9019e3 | 20 | |
andrewboyson | 4:6a1d887f1cad | 21 | uint8_t v [ 4]; //version |
andrewboyson | 4:6a1d887f1cad | 22 | uint8_t n [128]; //modulus |
andrewboyson | 4:6a1d887f1cad | 23 | uint8_t e [ 4]; //publicExponent |
andrewboyson | 4:6a1d887f1cad | 24 | uint8_t d [128]; //privateExponent |
andrewboyson | 4:6a1d887f1cad | 25 | uint8_t p [ 64]; //prime1 |
andrewboyson | 4:6a1d887f1cad | 26 | uint8_t q [ 64]; //prime2 |
andrewboyson | 4:6a1d887f1cad | 27 | uint8_t dp [ 64]; //exponent1 -- d mod (p-1) |
andrewboyson | 4:6a1d887f1cad | 28 | uint8_t dq [ 64]; //exponent2 -- d mod (q-1) |
andrewboyson | 4:6a1d887f1cad | 29 | uint8_t invq[ 64]; //coefficient -- (inverse of q) mod p |
andrewboyson | 0:be515c9019e3 | 30 | |
andrewboyson | 0:be515c9019e3 | 31 | static const char* pNext; |
andrewboyson | 0:be515c9019e3 | 32 | static const char* buffer = |
andrewboyson | 0:be515c9019e3 | 33 | #include "pri-key.inc" |
andrewboyson | 0:be515c9019e3 | 34 | ; |
andrewboyson | 0:be515c9019e3 | 35 | static char readChar() |
andrewboyson | 0:be515c9019e3 | 36 | { |
andrewboyson | 0:be515c9019e3 | 37 | char c = *pNext; |
andrewboyson | 0:be515c9019e3 | 38 | if (!c) return 0; |
andrewboyson | 0:be515c9019e3 | 39 | pNext++; |
andrewboyson | 0:be515c9019e3 | 40 | return c; |
andrewboyson | 0:be515c9019e3 | 41 | } |
andrewboyson | 0:be515c9019e3 | 42 | static int readLength() |
andrewboyson | 0:be515c9019e3 | 43 | { |
andrewboyson | 0:be515c9019e3 | 44 | int c = Base64ReadByte(); |
andrewboyson | 0:be515c9019e3 | 45 | if (c == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 46 | if (c < 0x80) return c; //Single byte length |
andrewboyson | 0:be515c9019e3 | 47 | if (c == 0x80) return -1; //indefinite form - do not use |
andrewboyson | 0:be515c9019e3 | 48 | int numberOfBytes = c - 0x80; |
andrewboyson | 0:be515c9019e3 | 49 | int len = 0; |
andrewboyson | 0:be515c9019e3 | 50 | for (int i = 0; i < numberOfBytes; i++) |
andrewboyson | 0:be515c9019e3 | 51 | { |
andrewboyson | 0:be515c9019e3 | 52 | len <<= 8; |
andrewboyson | 0:be515c9019e3 | 53 | c = Base64ReadByte(); |
andrewboyson | 0:be515c9019e3 | 54 | if (c == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 55 | len |= c; |
andrewboyson | 0:be515c9019e3 | 56 | } |
andrewboyson | 0:be515c9019e3 | 57 | return len; |
andrewboyson | 0:be515c9019e3 | 58 | } |
andrewboyson | 0:be515c9019e3 | 59 | static int readSequence() |
andrewboyson | 0:be515c9019e3 | 60 | { |
andrewboyson | 0:be515c9019e3 | 61 | int c = Base64ReadByte(); |
andrewboyson | 0:be515c9019e3 | 62 | if (c == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 63 | if (c != 0x30) return -1; //Not SEQUENCE type |
andrewboyson | 0:be515c9019e3 | 64 | int len = readLength(); |
andrewboyson | 0:be515c9019e3 | 65 | return len; |
andrewboyson | 0:be515c9019e3 | 66 | } |
andrewboyson | 4:6a1d887f1cad | 67 | static int readData(uint8_t* data, int size) //Reads the data from big-endian 'pem' format into little-endian 'bn' format |
andrewboyson | 0:be515c9019e3 | 68 | { |
andrewboyson | 0:be515c9019e3 | 69 | int c = Base64ReadByte(); |
andrewboyson | 0:be515c9019e3 | 70 | if (c == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 71 | if (c != 0x02) return -1; //Not INTEGER type |
andrewboyson | 0:be515c9019e3 | 72 | int pemLength = readLength(); |
andrewboyson | 0:be515c9019e3 | 73 | if (pemLength == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 74 | |
andrewboyson | 0:be515c9019e3 | 75 | int finalLength = pemLength; |
andrewboyson | 0:be515c9019e3 | 76 | for (int i = 0; i < pemLength; i++) |
andrewboyson | 0:be515c9019e3 | 77 | { |
andrewboyson | 0:be515c9019e3 | 78 | c = Base64ReadByte(); |
andrewboyson | 0:be515c9019e3 | 79 | if (c == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 80 | if (!i && !c) //Don't add if this is the msb and that byte is zero but reduce the final length by 1 |
andrewboyson | 0:be515c9019e3 | 81 | { |
andrewboyson | 0:be515c9019e3 | 82 | finalLength--; |
andrewboyson | 0:be515c9019e3 | 83 | } |
andrewboyson | 0:be515c9019e3 | 84 | else |
andrewboyson | 0:be515c9019e3 | 85 | { |
andrewboyson | 0:be515c9019e3 | 86 | data[pemLength - 1 - i] = c; //If pemLength is one too big then 'i' will also be one too big so the result is correct |
andrewboyson | 0:be515c9019e3 | 87 | } |
andrewboyson | 0:be515c9019e3 | 88 | } |
andrewboyson | 0:be515c9019e3 | 89 | for (int i = finalLength; i < size; i++) data[i] = 0; |
andrewboyson | 0:be515c9019e3 | 90 | |
andrewboyson | 0:be515c9019e3 | 91 | return finalLength + 1; |
andrewboyson | 0:be515c9019e3 | 92 | } |
andrewboyson | 0:be515c9019e3 | 93 | void PriKeyInit() |
andrewboyson | 0:be515c9019e3 | 94 | { |
andrewboyson | 0:be515c9019e3 | 95 | pNext = buffer; |
andrewboyson | 0:be515c9019e3 | 96 | Base64ReadNextCharFunctionPointer = readChar; |
andrewboyson | 0:be515c9019e3 | 97 | |
andrewboyson | 0:be515c9019e3 | 98 | int r = 0; |
andrewboyson | 0:be515c9019e3 | 99 | r = Base64SkipLine(); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 100 | r = readSequence(); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 101 | |
andrewboyson | 0:be515c9019e3 | 102 | r = readData( v, sizeof( v)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 103 | r = readData( n, sizeof( n)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 104 | r = readData( e, sizeof( e)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 105 | r = readData( d, sizeof( d)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 106 | r = readData( p, sizeof( p)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 107 | r = readData( q, sizeof( q)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 108 | r = readData( dp, sizeof( dp)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 109 | r = readData( dq, sizeof( dq)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 110 | r = readData(invq, sizeof(invq)); if (r < 0) return; |
andrewboyson | 0:be515c9019e3 | 111 | |
andrewboyson | 0:be515c9019e3 | 112 | Log("Primary key content\r\n"); |
andrewboyson | 0:be515c9019e3 | 113 | LogBytesAsHex( v, sizeof( v)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 114 | LogBytesAsHex( n, sizeof( n)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 115 | LogBytesAsHex( e, sizeof( e)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 116 | LogBytesAsHex( d, sizeof( d)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 117 | LogBytesAsHex( p, sizeof( p)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 118 | LogBytesAsHex( q, sizeof( q)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 119 | LogBytesAsHex( dp, sizeof( dp)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 120 | LogBytesAsHex( dq, sizeof( dq)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 121 | LogBytesAsHex(invq, sizeof(invq)); Log("\n\n"); |
andrewboyson | 0:be515c9019e3 | 122 | } |
andrewboyson | 4:6a1d887f1cad | 123 | int PriKeyDecryptStart(uint8_t* message) //return the slot number for the decryption |
andrewboyson | 0:be515c9019e3 | 124 | { |
andrewboyson | 1:9c66a551a67e | 125 | //Convert message to big number (little endian) format prior to decryption |
andrewboyson | 4:6a1d887f1cad | 126 | uint8_t leMessage[128]; |
andrewboyson | 1:9c66a551a67e | 127 | for (int i = 0; i < 128; i++) leMessage[127 - i] = message[i]; |
andrewboyson | 14:03a0b8fd6ddc | 128 | return RsaStart((uint32_t*)leMessage, (uint32_t*)p, (uint32_t*)q, (uint32_t*)dp, (uint32_t*)dq, (uint32_t*)invq); |
andrewboyson | 2:82268409e83f | 129 | } |
andrewboyson | 2:82268409e83f | 130 | bool PriKeyDecryptFinished(int slot) |
andrewboyson | 2:82268409e83f | 131 | { |
andrewboyson | 14:03a0b8fd6ddc | 132 | return RsaFinished(slot); |
andrewboyson | 0:be515c9019e3 | 133 | } |
andrewboyson | 14:03a0b8fd6ddc | 134 | uint8_t* PriKeyDecryptResult(int slot) |
andrewboyson | 0:be515c9019e3 | 135 | { |
andrewboyson | 14:03a0b8fd6ddc | 136 | return (uint8_t*) RsaResult(slot); |
andrewboyson | 2:82268409e83f | 137 | } |
andrewboyson | 2:82268409e83f | 138 | void PriKeyDecryptClear(int slot) |
andrewboyson | 2:82268409e83f | 139 | { |
andrewboyson | 14:03a0b8fd6ddc | 140 | RsaClear(slot); |
andrewboyson | 0:be515c9019e3 | 141 | } |