A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Sep 26 07:19:09 2019 +0000
Revision:
12:2c342345b3db
Parent:
10:e269fd7b9500
Child:
14:03a0b8fd6ddc
Chinese remainder theorem implemented giving a useful reduction from 20s to 5s to decrypt RSA.

Who changed what in which revision?

UserRevisionLine numberNew 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 12:2c342345b3db 128 //return RsaSlowStart((uint32_t*)leMessage, (uint32_t*)d, (uint32_t*)n);
andrewboyson 12:2c342345b3db 129 return RsaFastStart((uint32_t*)leMessage, (uint32_t*)p, (uint32_t*)q, (uint32_t*)dp, (uint32_t*)dq, (uint32_t*)invq);
andrewboyson 2:82268409e83f 130 }
andrewboyson 2:82268409e83f 131 bool PriKeyDecryptFinished(int slot)
andrewboyson 2:82268409e83f 132 {
andrewboyson 12:2c342345b3db 133 //return RsaSlowFinished(slot);
andrewboyson 12:2c342345b3db 134 return RsaFastFinished(slot);
andrewboyson 0:be515c9019e3 135 }
andrewboyson 4:6a1d887f1cad 136 uint8_t* PriKeyDecryptGetResult(int slot)
andrewboyson 0:be515c9019e3 137 {
andrewboyson 12:2c342345b3db 138 //return (uint8_t*) RsaSlowResult(slot);
andrewboyson 12:2c342345b3db 139 return (uint8_t*) RsaFastResult(slot);
andrewboyson 2:82268409e83f 140 }
andrewboyson 2:82268409e83f 141 void PriKeyDecryptClear(int slot)
andrewboyson 2:82268409e83f 142 {
andrewboyson 12:2c342345b3db 143 //RsaSlowClear(slot);
andrewboyson 12:2c342345b3db 144 RsaFastClear(slot);
andrewboyson 12:2c342345b3db 145 }
andrewboyson 12:2c342345b3db 146 int PriKeyFastStart(uint8_t* message) //return the slot number for the decryption
andrewboyson 12:2c342345b3db 147 {
andrewboyson 12:2c342345b3db 148 //Convert message to big number (little endian) format prior to decryption
andrewboyson 12:2c342345b3db 149 uint8_t leMessage[128];
andrewboyson 12:2c342345b3db 150 for (int i = 0; i < 128; i++) leMessage[127 - i] = message[i];
andrewboyson 12:2c342345b3db 151 return RsaFastStart((uint32_t*)leMessage, (uint32_t*)p, (uint32_t*)q, (uint32_t*)dp, (uint32_t*)dq, (uint32_t*)invq);
andrewboyson 12:2c342345b3db 152 }
andrewboyson 12:2c342345b3db 153 bool PriKeyFastFinished(int slot)
andrewboyson 12:2c342345b3db 154 {
andrewboyson 12:2c342345b3db 155 return RsaFastFinished(slot);
andrewboyson 12:2c342345b3db 156 }
andrewboyson 12:2c342345b3db 157 uint8_t* PriKeyFastGetResult(int slot)
andrewboyson 12:2c342345b3db 158 {
andrewboyson 12:2c342345b3db 159 return (uint8_t*) RsaFastResult(slot);
andrewboyson 12:2c342345b3db 160 }
andrewboyson 12:2c342345b3db 161 void PriKeyFastClear(int slot)
andrewboyson 12:2c342345b3db 162 {
andrewboyson 12:2c342345b3db 163 RsaFastClear(slot);
andrewboyson 0:be515c9019e3 164 }