A simple library to support serving https.
Dependents: oldheating gps motorhome heating
aes-gcm/gcm.h@24:cb43290fc439, 2020-04-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Apr 01 12:48:52 2020 +0000
- Revision:
- 24:cb43290fc439
- Parent:
- 6:819c17738dc2
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?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 6:819c17738dc2 | 1 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 2 | * |
andrewboyson | 6:819c17738dc2 | 3 | * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL |
andrewboyson | 6:819c17738dc2 | 4 | * |
andrewboyson | 6:819c17738dc2 | 5 | * This is a simple and straightforward implementation of AES-GCM authenticated |
andrewboyson | 6:819c17738dc2 | 6 | * encryption. The focus of this work was correctness & accuracy. It is written |
andrewboyson | 6:819c17738dc2 | 7 | * in straight 'C' without any particular focus upon optimization or speed. It |
andrewboyson | 6:819c17738dc2 | 8 | * should be endian (memory byte order) neutral since the few places that care |
andrewboyson | 6:819c17738dc2 | 9 | * are handled explicitly. |
andrewboyson | 6:819c17738dc2 | 10 | * |
andrewboyson | 6:819c17738dc2 | 11 | * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com. |
andrewboyson | 6:819c17738dc2 | 12 | * |
andrewboyson | 6:819c17738dc2 | 13 | * It is intended for general purpose use, but was written in support of GRC's |
andrewboyson | 6:819c17738dc2 | 14 | * reference implementation of the SQRL (Secure Quick Reliable Login) client. |
andrewboyson | 6:819c17738dc2 | 15 | * |
andrewboyson | 6:819c17738dc2 | 16 | * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf |
andrewboyson | 6:819c17738dc2 | 17 | * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \ |
andrewboyson | 6:819c17738dc2 | 18 | * gcm/gcm-revised-spec.pdf |
andrewboyson | 6:819c17738dc2 | 19 | * |
andrewboyson | 6:819c17738dc2 | 20 | * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE |
andrewboyson | 6:819c17738dc2 | 21 | * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK. |
andrewboyson | 6:819c17738dc2 | 22 | * |
andrewboyson | 6:819c17738dc2 | 23 | *******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 24 | #ifndef GCM_HEADER |
andrewboyson | 6:819c17738dc2 | 25 | #define GCM_HEADER |
andrewboyson | 6:819c17738dc2 | 26 | |
andrewboyson | 6:819c17738dc2 | 27 | #define GCM_AUTH_FAILURE 0x55555555 // authentication failure |
andrewboyson | 6:819c17738dc2 | 28 | |
andrewboyson | 6:819c17738dc2 | 29 | #include "aes.h" // gcm_context includes aes_context |
andrewboyson | 6:819c17738dc2 | 30 | |
andrewboyson | 6:819c17738dc2 | 31 | #if defined(_MSC_VER) |
andrewboyson | 6:819c17738dc2 | 32 | #include <basetsd.h> |
andrewboyson | 6:819c17738dc2 | 33 | typedef unsigned int size_t;// use the right type for length declarations |
andrewboyson | 6:819c17738dc2 | 34 | typedef UINT32 uint32_t; |
andrewboyson | 6:819c17738dc2 | 35 | typedef UINT64 uint64_t; |
andrewboyson | 6:819c17738dc2 | 36 | #else |
andrewboyson | 6:819c17738dc2 | 37 | #include <stdint.h> |
andrewboyson | 6:819c17738dc2 | 38 | #endif |
andrewboyson | 6:819c17738dc2 | 39 | |
andrewboyson | 6:819c17738dc2 | 40 | |
andrewboyson | 6:819c17738dc2 | 41 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 42 | * GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx |
andrewboyson | 6:819c17738dc2 | 43 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 44 | typedef struct { |
andrewboyson | 6:819c17738dc2 | 45 | int mode; // cipher direction: encrypt/decrypt |
andrewboyson | 6:819c17738dc2 | 46 | uint64_t len; // cipher data length processed so far |
andrewboyson | 6:819c17738dc2 | 47 | uint64_t add_len; // total add data length |
andrewboyson | 6:819c17738dc2 | 48 | uint64_t HL[16]; // precalculated lo-half HTable |
andrewboyson | 6:819c17738dc2 | 49 | uint64_t HH[16]; // precalculated hi-half HTable |
andrewboyson | 6:819c17738dc2 | 50 | uchar base_ectr[16]; // first counter-mode cipher output for tag |
andrewboyson | 6:819c17738dc2 | 51 | uchar y[16]; // the current cipher-input IV|Counter value |
andrewboyson | 6:819c17738dc2 | 52 | uchar buf[16]; // buf working value |
andrewboyson | 6:819c17738dc2 | 53 | aes_context aes_ctx; // cipher context used |
andrewboyson | 6:819c17738dc2 | 54 | } gcm_context; |
andrewboyson | 6:819c17738dc2 | 55 | |
andrewboyson | 6:819c17738dc2 | 56 | |
andrewboyson | 6:819c17738dc2 | 57 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 58 | * GCM_CONTEXT : MUST be called once before ANY use of this library |
andrewboyson | 6:819c17738dc2 | 59 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 60 | int gcm_initialize( void ); |
andrewboyson | 6:819c17738dc2 | 61 | |
andrewboyson | 6:819c17738dc2 | 62 | |
andrewboyson | 6:819c17738dc2 | 63 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 64 | * GCM_SETKEY : sets the GCM (and AES) keying material for use |
andrewboyson | 6:819c17738dc2 | 65 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 66 | int gcm_setkey( gcm_context *ctx, // caller-provided context ptr |
andrewboyson | 6:819c17738dc2 | 67 | const uchar *key, // pointer to cipher key |
andrewboyson | 6:819c17738dc2 | 68 | const uint keysize // must be 128, 192 or 256 |
andrewboyson | 6:819c17738dc2 | 69 | ); // returns 0 for success |
andrewboyson | 6:819c17738dc2 | 70 | |
andrewboyson | 6:819c17738dc2 | 71 | |
andrewboyson | 6:819c17738dc2 | 72 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 73 | * |
andrewboyson | 6:819c17738dc2 | 74 | * GCM_CRYPT_AND_TAG |
andrewboyson | 6:819c17738dc2 | 75 | * |
andrewboyson | 6:819c17738dc2 | 76 | * This either encrypts or decrypts the user-provided data and, either |
andrewboyson | 6:819c17738dc2 | 77 | * way, generates an authentication tag of the requested length. It must be |
andrewboyson | 6:819c17738dc2 | 78 | * called with a GCM context whose key has already been set with GCM_SETKEY. |
andrewboyson | 6:819c17738dc2 | 79 | * |
andrewboyson | 6:819c17738dc2 | 80 | * The user would typically call this explicitly to ENCRYPT a buffer of data |
andrewboyson | 6:819c17738dc2 | 81 | * and optional associated data, and produce its an authentication tag. |
andrewboyson | 6:819c17738dc2 | 82 | * |
andrewboyson | 6:819c17738dc2 | 83 | * To reverse the process the user would typically call the companion |
andrewboyson | 6:819c17738dc2 | 84 | * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided |
andrewboyson | 6:819c17738dc2 | 85 | * authentication tag. The GCM_AUTH_DECRYPT function calls this function |
andrewboyson | 6:819c17738dc2 | 86 | * to perform its decryption and tag generation, which it then compares. |
andrewboyson | 6:819c17738dc2 | 87 | * |
andrewboyson | 6:819c17738dc2 | 88 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 89 | int gcm_crypt_and_tag( |
andrewboyson | 6:819c17738dc2 | 90 | gcm_context *ctx, // gcm context with key already setup |
andrewboyson | 6:819c17738dc2 | 91 | int mode, // cipher direction: GCM_ENCRYPT or GCM_DECRYPT |
andrewboyson | 6:819c17738dc2 | 92 | const uchar *iv, // pointer to the 12-byte initialization vector |
andrewboyson | 6:819c17738dc2 | 93 | size_t iv_len, // byte length if the IV. should always be 12 |
andrewboyson | 6:819c17738dc2 | 94 | const uchar *add, // pointer to the non-ciphered additional data |
andrewboyson | 6:819c17738dc2 | 95 | size_t add_len, // byte length of the additional AEAD data |
andrewboyson | 6:819c17738dc2 | 96 | const uchar *input, // pointer to the cipher data source |
andrewboyson | 6:819c17738dc2 | 97 | uchar *output, // pointer to the cipher data destination |
andrewboyson | 6:819c17738dc2 | 98 | size_t length, // byte length of the cipher data |
andrewboyson | 6:819c17738dc2 | 99 | uchar *tag, // pointer to the tag to be generated |
andrewboyson | 6:819c17738dc2 | 100 | size_t tag_len ); // byte length of the tag to be generated |
andrewboyson | 6:819c17738dc2 | 101 | |
andrewboyson | 6:819c17738dc2 | 102 | |
andrewboyson | 6:819c17738dc2 | 103 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 104 | * |
andrewboyson | 6:819c17738dc2 | 105 | * GCM_AUTH_DECRYPT |
andrewboyson | 6:819c17738dc2 | 106 | * |
andrewboyson | 6:819c17738dc2 | 107 | * This DECRYPTS a user-provided data buffer with optional associated data. |
andrewboyson | 6:819c17738dc2 | 108 | * It then verifies a user-supplied authentication tag against the tag just |
andrewboyson | 6:819c17738dc2 | 109 | * re-created during decryption to verify that the data has not been altered. |
andrewboyson | 6:819c17738dc2 | 110 | * |
andrewboyson | 6:819c17738dc2 | 111 | * This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption |
andrewboyson | 6:819c17738dc2 | 112 | * and authentication tag generation. |
andrewboyson | 6:819c17738dc2 | 113 | * |
andrewboyson | 6:819c17738dc2 | 114 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 115 | int gcm_auth_decrypt( |
andrewboyson | 6:819c17738dc2 | 116 | gcm_context *ctx, // gcm context with key already setup |
andrewboyson | 6:819c17738dc2 | 117 | const uchar *iv, // pointer to the 12-byte initialization vector |
andrewboyson | 6:819c17738dc2 | 118 | size_t iv_len, // byte length if the IV. should always be 12 |
andrewboyson | 6:819c17738dc2 | 119 | const uchar *add, // pointer to the non-ciphered additional data |
andrewboyson | 6:819c17738dc2 | 120 | size_t add_len, // byte length of the additional AEAD data |
andrewboyson | 6:819c17738dc2 | 121 | const uchar *input, // pointer to the cipher data source |
andrewboyson | 6:819c17738dc2 | 122 | uchar *output, // pointer to the cipher data destination |
andrewboyson | 6:819c17738dc2 | 123 | size_t length, // byte length of the cipher data |
andrewboyson | 6:819c17738dc2 | 124 | const uchar *tag, // pointer to the tag to be authenticated |
andrewboyson | 6:819c17738dc2 | 125 | size_t tag_len ); // byte length of the tag <= 16 |
andrewboyson | 6:819c17738dc2 | 126 | |
andrewboyson | 6:819c17738dc2 | 127 | |
andrewboyson | 6:819c17738dc2 | 128 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 129 | * |
andrewboyson | 6:819c17738dc2 | 130 | * GCM_START |
andrewboyson | 6:819c17738dc2 | 131 | * |
andrewboyson | 6:819c17738dc2 | 132 | * Given a user-provided GCM context, this initializes it, sets the encryption |
andrewboyson | 6:819c17738dc2 | 133 | * mode, and preprocesses the initialization vector and additional AEAD data. |
andrewboyson | 6:819c17738dc2 | 134 | * |
andrewboyson | 6:819c17738dc2 | 135 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 136 | int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context |
andrewboyson | 6:819c17738dc2 | 137 | int mode, // GCM_ENCRYPT or GCM_DECRYPT |
andrewboyson | 6:819c17738dc2 | 138 | const uchar *iv, // pointer to initialization vector |
andrewboyson | 6:819c17738dc2 | 139 | size_t iv_len, // IV length in bytes (should == 12) |
andrewboyson | 6:819c17738dc2 | 140 | const uchar *add, // pointer to additional AEAD data (NULL if none) |
andrewboyson | 6:819c17738dc2 | 141 | size_t add_len ); // length of additional AEAD data (bytes) |
andrewboyson | 6:819c17738dc2 | 142 | |
andrewboyson | 6:819c17738dc2 | 143 | |
andrewboyson | 6:819c17738dc2 | 144 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 145 | * |
andrewboyson | 6:819c17738dc2 | 146 | * GCM_UPDATE |
andrewboyson | 6:819c17738dc2 | 147 | * |
andrewboyson | 6:819c17738dc2 | 148 | * This is called once or more to process bulk plaintext or ciphertext data. |
andrewboyson | 6:819c17738dc2 | 149 | * We give this some number of bytes of input and it returns the same number |
andrewboyson | 6:819c17738dc2 | 150 | * of output bytes. If called multiple times (which is fine) all but the final |
andrewboyson | 6:819c17738dc2 | 151 | * invocation MUST be called with length mod 16 == 0. (Only the final call can |
andrewboyson | 6:819c17738dc2 | 152 | * have a partial block length of < 128 bits.) |
andrewboyson | 6:819c17738dc2 | 153 | * |
andrewboyson | 6:819c17738dc2 | 154 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 155 | int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context |
andrewboyson | 6:819c17738dc2 | 156 | size_t length, // length, in bytes, of data to process |
andrewboyson | 6:819c17738dc2 | 157 | const uchar *input, // pointer to source data |
andrewboyson | 6:819c17738dc2 | 158 | uchar *output ); // pointer to destination data |
andrewboyson | 6:819c17738dc2 | 159 | |
andrewboyson | 6:819c17738dc2 | 160 | |
andrewboyson | 6:819c17738dc2 | 161 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 162 | * |
andrewboyson | 6:819c17738dc2 | 163 | * GCM_FINISH |
andrewboyson | 6:819c17738dc2 | 164 | * |
andrewboyson | 6:819c17738dc2 | 165 | * This is called once after all calls to GCM_UPDATE to finalize the GCM. |
andrewboyson | 6:819c17738dc2 | 166 | * It performs the final GHASH to produce the resulting authentication TAG. |
andrewboyson | 6:819c17738dc2 | 167 | * |
andrewboyson | 6:819c17738dc2 | 168 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 169 | int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context |
andrewboyson | 6:819c17738dc2 | 170 | uchar *tag, // ptr to tag buffer - NULL if tag_len = 0 |
andrewboyson | 6:819c17738dc2 | 171 | size_t tag_len ); // length, in bytes, of the tag-receiving buf |
andrewboyson | 6:819c17738dc2 | 172 | |
andrewboyson | 6:819c17738dc2 | 173 | |
andrewboyson | 6:819c17738dc2 | 174 | /****************************************************************************** |
andrewboyson | 6:819c17738dc2 | 175 | * |
andrewboyson | 6:819c17738dc2 | 176 | * GCM_ZERO_CTX |
andrewboyson | 6:819c17738dc2 | 177 | * |
andrewboyson | 6:819c17738dc2 | 178 | * The GCM context contains both the GCM context and the AES context. |
andrewboyson | 6:819c17738dc2 | 179 | * This includes keying and key-related material which is security- |
andrewboyson | 6:819c17738dc2 | 180 | * sensitive, so it MUST be zeroed after use. This function does that. |
andrewboyson | 6:819c17738dc2 | 181 | * |
andrewboyson | 6:819c17738dc2 | 182 | ******************************************************************************/ |
andrewboyson | 6:819c17738dc2 | 183 | void gcm_zero_ctx( gcm_context *ctx ); |
andrewboyson | 6:819c17738dc2 | 184 | |
andrewboyson | 6:819c17738dc2 | 185 | |
andrewboyson | 6:819c17738dc2 | 186 | #endif /* GCM_HEADER */ |