DeepCover Embedded Security in IoT: Public-key Secured Data Paths

Dependencies:   MaximInterface

The MAXREFDES155# is an internet-of-things (IoT) embedded-security reference design, built to authenticate and control a sensing node using elliptic-curve-based public-key cryptography with control and notification from a web server.

The hardware includes an ARM® mbed™ shield and attached sensor endpoint. The shield contains a DS2476 DeepCover® ECDSA/SHA-2 coprocessor, Wifi communication, LCD push-button controls, and status LEDs. The sensor endpoint is attached to the shield using a 300mm cable and contains a DS28C36 DeepCover ECDSA/SHA-2 authenticator, IR-thermal sensor, and aiming laser for the IR sensor. The MAXREFDES155# is equipped with a standard Arduino® form-factor shield connector for immediate testing using an mbed board such as the MAX32600MBED#. The combination of these two devices represent an IoT device. Communication to the web server is accomplished with the shield Wifi circuitry. Communication from the shield to the attached sensor module is accomplished over I2C . The sensor module represents an IoT endpoint that generates small data with a requirement for message authenticity/integrity and secure on/off operational control.

The design is hierarchical with each mbed platform and shield communicating data from the sensor node to a web server that maintains a centralized log and dispatches notifications as necessary. The simplicity of this design enables rapid integration into any star-topology IoT network to provide security with the low overhead and cost provided by the ECDSA-P256 asymmetric-key and SHA-256 symmetric-key algorithms.

More information about the MAXREFDES155# is available on the Maxim Integrated website.

Committer:
IanBenzMaxim
Date:
Fri Jan 19 10:28:27 2018 -0600
Revision:
15:75404fab3615
Parent:
0:33d4e66780c0
Updated MaximInterface revision.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 0:33d4e66780c0 1 /*******************************************************************************
IanBenzMaxim 0:33d4e66780c0 2 * Copyright (C) 2013 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 0:33d4e66780c0 3 *
IanBenzMaxim 0:33d4e66780c0 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 0:33d4e66780c0 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 0:33d4e66780c0 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 0:33d4e66780c0 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 0:33d4e66780c0 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 0:33d4e66780c0 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 0:33d4e66780c0 10 *
IanBenzMaxim 0:33d4e66780c0 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 0:33d4e66780c0 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 0:33d4e66780c0 13 *
IanBenzMaxim 0:33d4e66780c0 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 0:33d4e66780c0 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 0:33d4e66780c0 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 0:33d4e66780c0 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 0:33d4e66780c0 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 0:33d4e66780c0 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 0:33d4e66780c0 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 0:33d4e66780c0 21 *
IanBenzMaxim 0:33d4e66780c0 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 24 * Products, Inc. Branding Policy.
IanBenzMaxim 0:33d4e66780c0 25 *
IanBenzMaxim 0:33d4e66780c0 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 0:33d4e66780c0 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 0:33d4e66780c0 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 0:33d4e66780c0 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 0:33d4e66780c0 30 * ownership rights.
IanBenzMaxim 0:33d4e66780c0 31 *******************************************************************************
IanBenzMaxim 0:33d4e66780c0 32 */
IanBenzMaxim 0:33d4e66780c0 33
IanBenzMaxim 0:33d4e66780c0 34 #include <string.h>
IanBenzMaxim 0:33d4e66780c0 35
IanBenzMaxim 0:33d4e66780c0 36 typedef unsigned char uchar;
IanBenzMaxim 0:33d4e66780c0 37 typedef unsigned short ushort;
IanBenzMaxim 0:33d4e66780c0 38 typedef unsigned long ulong;
IanBenzMaxim 0:33d4e66780c0 39
IanBenzMaxim 0:33d4e66780c0 40 #define SHA_256_INITIAL_LENGTH 8
IanBenzMaxim 0:33d4e66780c0 41
IanBenzMaxim 0:33d4e66780c0 42 #define TRUE 1
IanBenzMaxim 0:33d4e66780c0 43 #define FALSE 0
IanBenzMaxim 0:33d4e66780c0 44
IanBenzMaxim 0:33d4e66780c0 45 // General Purpose SHA-256 Function
IanBenzMaxim 0:33d4e66780c0 46 void ComputeSHA256(uchar* message, short length, ushort skipconst, ushort reverse, uchar* digest);
IanBenzMaxim 0:33d4e66780c0 47
IanBenzMaxim 0:33d4e66780c0 48 // Utility Functions
IanBenzMaxim 0:33d4e66780c0 49 static ulong sha_ch(ulong x, ulong y, ulong z);
IanBenzMaxim 0:33d4e66780c0 50 static ulong sha_maj(ulong x, ulong y, ulong z);
IanBenzMaxim 0:33d4e66780c0 51 static ulong sha_rotr_32(ulong val, ushort r);
IanBenzMaxim 0:33d4e66780c0 52 static ulong sha_shr_32(ulong val, ushort r);
IanBenzMaxim 0:33d4e66780c0 53 static ulong sha_bigsigma256_0(ulong x);
IanBenzMaxim 0:33d4e66780c0 54 static ulong sha_littlesigma256_0(ulong x);
IanBenzMaxim 0:33d4e66780c0 55 static ulong sha_littlesigma256_1(ulong x);
IanBenzMaxim 0:33d4e66780c0 56 static void sha_copy32(const ulong* p1, ulong* p2, ushort length);
IanBenzMaxim 0:33d4e66780c0 57 static void sha_copyWordsToBytes32(const ulong* input, uchar* output, ushort numwords);
IanBenzMaxim 0:33d4e66780c0 58 static void sha_writeResult(ushort reverse, uchar* outpointer, const ulong* H32);
IanBenzMaxim 0:33d4e66780c0 59 static ulong sha_getW(int index, ulong* W32);
IanBenzMaxim 0:33d4e66780c0 60 static void sha_prepareSchedule(const uchar* message, ulong* W32);
IanBenzMaxim 0:33d4e66780c0 61 static void sha256_hashblock(const uchar* message, ushort lastblock, ulong* H32);
IanBenzMaxim 0:33d4e66780c0 62
IanBenzMaxim 0:33d4e66780c0 63 // External Debug print
IanBenzMaxim 0:33d4e66780c0 64 #ifdef DEBUG_SHA
IanBenzMaxim 0:33d4e66780c0 65 extern int dprintf(char *format, ...);
IanBenzMaxim 0:33d4e66780c0 66 #endif
IanBenzMaxim 0:33d4e66780c0 67
IanBenzMaxim 0:33d4e66780c0 68 // SHA-256 globals values
IanBenzMaxim 0:33d4e66780c0 69 static const ulong SHA_256_Initial[] =
IanBenzMaxim 0:33d4e66780c0 70 {
IanBenzMaxim 0:33d4e66780c0 71 0x6a09e667,
IanBenzMaxim 0:33d4e66780c0 72 0xbb67ae85,
IanBenzMaxim 0:33d4e66780c0 73 0x3c6ef372,
IanBenzMaxim 0:33d4e66780c0 74 0xa54ff53a,
IanBenzMaxim 0:33d4e66780c0 75 0x510e527f,
IanBenzMaxim 0:33d4e66780c0 76 0x9b05688c,
IanBenzMaxim 0:33d4e66780c0 77 0x1f83d9ab,
IanBenzMaxim 0:33d4e66780c0 78 0x5be0cd19
IanBenzMaxim 0:33d4e66780c0 79 };
IanBenzMaxim 0:33d4e66780c0 80
IanBenzMaxim 0:33d4e66780c0 81 static const ulong SHA_CONSTANTS[] =
IanBenzMaxim 0:33d4e66780c0 82 {
IanBenzMaxim 0:33d4e66780c0 83 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
IanBenzMaxim 0:33d4e66780c0 84 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
IanBenzMaxim 0:33d4e66780c0 85 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
IanBenzMaxim 0:33d4e66780c0 86 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
IanBenzMaxim 0:33d4e66780c0 87 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
IanBenzMaxim 0:33d4e66780c0 88 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
IanBenzMaxim 0:33d4e66780c0 89 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
IanBenzMaxim 0:33d4e66780c0 90 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
IanBenzMaxim 0:33d4e66780c0 91 0xca273ece, 0xd186b8c7, 0xeada7dd6, 0xf57d4f7f, 0x06f067aa, 0x0a637dc5, 0x113f9804, 0x1b710b35,
IanBenzMaxim 0:33d4e66780c0 92 0x28db77f5, 0x32caab7b, 0x3c9ebe0a, 0x431d67c4, 0x4cc5d4be, 0x597f299c, 0x5fcb6fab, 0x6c44198c
IanBenzMaxim 0:33d4e66780c0 93 };
IanBenzMaxim 0:33d4e66780c0 94
IanBenzMaxim 0:33d4e66780c0 95 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 96 // ------ General Purpose SHA-256 Function
IanBenzMaxim 0:33d4e66780c0 97 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 98
IanBenzMaxim 0:33d4e66780c0 99 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 100 /// Computes SHA-256 given the data block 'message' with no padding.
IanBenzMaxim 0:33d4e66780c0 101 /// The result is returned in 'digest'.
IanBenzMaxim 0:33d4e66780c0 102 ///
IanBenzMaxim 0:33d4e66780c0 103 /// @param[in] message
IanBenzMaxim 0:33d4e66780c0 104 /// Buffer containing the message to hash
IanBenzMaxim 0:33d4e66780c0 105 /// @param[in] skipconst
IanBenzMaxim 0:33d4e66780c0 106 /// Flag to skip adding constant on last block (skipconst=1) (Required for Maxim devices)
IanBenzMaxim 0:33d4e66780c0 107 /// @param[in] reverse
IanBenzMaxim 0:33d4e66780c0 108 /// Flag to reverse order of digest (reverse=1, MSWord first, LSByte first) (Required for Maxim devices)
IanBenzMaxim 0:33d4e66780c0 109 /// @param[out] digest
IanBenzMaxim 0:33d4e66780c0 110 /// Pointer to result hash digest in byte order used by Maxim devices
IanBenzMaxim 0:33d4e66780c0 111 //
IanBenzMaxim 0:33d4e66780c0 112 void ComputeSHA256(uchar* message, short length, ushort skipconst, ushort reverse, uchar* digest)
IanBenzMaxim 0:33d4e66780c0 113 {
IanBenzMaxim 0:33d4e66780c0 114 const ushort wordsize = 32;
IanBenzMaxim 0:33d4e66780c0 115
IanBenzMaxim 0:33d4e66780c0 116 ushort bytes_per_block;
IanBenzMaxim 0:33d4e66780c0 117 ushort nonpaddedlength;
IanBenzMaxim 0:33d4e66780c0 118 ushort numblocks;
IanBenzMaxim 0:33d4e66780c0 119 ushort i,j;
IanBenzMaxim 0:33d4e66780c0 120 ulong bitlength;
IanBenzMaxim 0:33d4e66780c0 121 ushort markerwritten;
IanBenzMaxim 0:33d4e66780c0 122 ushort lastblock;
IanBenzMaxim 0:33d4e66780c0 123
IanBenzMaxim 0:33d4e66780c0 124 uchar workbuffer[128];
IanBenzMaxim 0:33d4e66780c0 125 ulong H32[8]; // last SHA result variables
IanBenzMaxim 0:33d4e66780c0 126
IanBenzMaxim 0:33d4e66780c0 127 #ifdef DEBUG_SHA
IanBenzMaxim 0:33d4e66780c0 128 dprintf("\nSHA-256 INPUT:\n");
IanBenzMaxim 0:33d4e66780c0 129 for (i = 0; i < length; i+=4)
IanBenzMaxim 0:33d4e66780c0 130 {
IanBenzMaxim 0:33d4e66780c0 131 for (j = 0; j < 4; j++)
IanBenzMaxim 0:33d4e66780c0 132 dprintf("%02X ",message[i+j]);
IanBenzMaxim 0:33d4e66780c0 133 dprintf("\n");
IanBenzMaxim 0:33d4e66780c0 134 }
IanBenzMaxim 0:33d4e66780c0 135 dprintf("\n");
IanBenzMaxim 0:33d4e66780c0 136 #endif
IanBenzMaxim 0:33d4e66780c0 137
IanBenzMaxim 0:33d4e66780c0 138 // if wordsize is 32 bits, we need 512 bit blocks. else 1024 bit blocks.
IanBenzMaxim 0:33d4e66780c0 139 // that means 16 words are in one message.
IanBenzMaxim 0:33d4e66780c0 140 bytes_per_block = 16 * (wordsize / 8);
IanBenzMaxim 0:33d4e66780c0 141 // 1 byte for the '80' that follows the message, 8 or 16 bytes of length
IanBenzMaxim 0:33d4e66780c0 142 nonpaddedlength = length + 1 + (wordsize/4);
IanBenzMaxim 0:33d4e66780c0 143 numblocks = nonpaddedlength / bytes_per_block;
IanBenzMaxim 0:33d4e66780c0 144 if ((nonpaddedlength % bytes_per_block) != 0)
IanBenzMaxim 0:33d4e66780c0 145 {
IanBenzMaxim 0:33d4e66780c0 146 // then there is some remainder we need to pad
IanBenzMaxim 0:33d4e66780c0 147 numblocks++;
IanBenzMaxim 0:33d4e66780c0 148 }
IanBenzMaxim 0:33d4e66780c0 149
IanBenzMaxim 0:33d4e66780c0 150 sha_copy32(SHA_256_Initial, H32, SHA_256_INITIAL_LENGTH);
IanBenzMaxim 0:33d4e66780c0 151
IanBenzMaxim 0:33d4e66780c0 152 bitlength = 8 * length;
IanBenzMaxim 0:33d4e66780c0 153 markerwritten = 0;
IanBenzMaxim 0:33d4e66780c0 154 // 'length' is our number of bytes remaining.
IanBenzMaxim 0:33d4e66780c0 155 for (i = 0; i < numblocks; i++)
IanBenzMaxim 0:33d4e66780c0 156 {
IanBenzMaxim 0:33d4e66780c0 157 if (length > bytes_per_block)
IanBenzMaxim 0:33d4e66780c0 158 {
IanBenzMaxim 0:33d4e66780c0 159 memcpy(workbuffer, message, bytes_per_block);
IanBenzMaxim 0:33d4e66780c0 160 length -= bytes_per_block;
IanBenzMaxim 0:33d4e66780c0 161 }
IanBenzMaxim 0:33d4e66780c0 162 else if (length==bytes_per_block)
IanBenzMaxim 0:33d4e66780c0 163 {
IanBenzMaxim 0:33d4e66780c0 164 memcpy(workbuffer, message, length);
IanBenzMaxim 0:33d4e66780c0 165 length = 0;
IanBenzMaxim 0:33d4e66780c0 166 }
IanBenzMaxim 0:33d4e66780c0 167 else // length is less than number of bytes in a block
IanBenzMaxim 0:33d4e66780c0 168 {
IanBenzMaxim 0:33d4e66780c0 169 memcpy(workbuffer, message, length);
IanBenzMaxim 0:33d4e66780c0 170 // message is now used for temporary space
IanBenzMaxim 0:33d4e66780c0 171 message = workbuffer + length;
IanBenzMaxim 0:33d4e66780c0 172 if (markerwritten == 0)
IanBenzMaxim 0:33d4e66780c0 173 {
IanBenzMaxim 0:33d4e66780c0 174 *message++ = 0x80;
IanBenzMaxim 0:33d4e66780c0 175 length++;
IanBenzMaxim 0:33d4e66780c0 176 }
IanBenzMaxim 0:33d4e66780c0 177
IanBenzMaxim 0:33d4e66780c0 178 while (length < bytes_per_block)
IanBenzMaxim 0:33d4e66780c0 179 {
IanBenzMaxim 0:33d4e66780c0 180 // this loop is inserting padding, in this case all zeroes
IanBenzMaxim 0:33d4e66780c0 181 *message++ = 0;
IanBenzMaxim 0:33d4e66780c0 182 length++;
IanBenzMaxim 0:33d4e66780c0 183 }
IanBenzMaxim 0:33d4e66780c0 184 length = 0;
IanBenzMaxim 0:33d4e66780c0 185 // signify that we have already written the 80h
IanBenzMaxim 0:33d4e66780c0 186 markerwritten = 1;
IanBenzMaxim 0:33d4e66780c0 187 }
IanBenzMaxim 0:33d4e66780c0 188
IanBenzMaxim 0:33d4e66780c0 189 // on the last block, put the bit length at the very end
IanBenzMaxim 0:33d4e66780c0 190 lastblock = (i == (numblocks - 1));
IanBenzMaxim 0:33d4e66780c0 191 if (lastblock)
IanBenzMaxim 0:33d4e66780c0 192 {
IanBenzMaxim 0:33d4e66780c0 193 // point at the last byte in the block
IanBenzMaxim 0:33d4e66780c0 194 message = workbuffer + bytes_per_block - 1;
IanBenzMaxim 0:33d4e66780c0 195 for (j = 0; j < wordsize/4; j++)
IanBenzMaxim 0:33d4e66780c0 196 {
IanBenzMaxim 0:33d4e66780c0 197 *message-- = (uchar)bitlength;
IanBenzMaxim 0:33d4e66780c0 198 bitlength = bitlength >> 8;
IanBenzMaxim 0:33d4e66780c0 199 }
IanBenzMaxim 0:33d4e66780c0 200 }
IanBenzMaxim 0:33d4e66780c0 201
IanBenzMaxim 0:33d4e66780c0 202 // SHA in software
IanBenzMaxim 0:33d4e66780c0 203 sha256_hashblock(workbuffer, (ushort)(lastblock && skipconst), H32);
IanBenzMaxim 0:33d4e66780c0 204 message += bytes_per_block;
IanBenzMaxim 0:33d4e66780c0 205 }
IanBenzMaxim 0:33d4e66780c0 206
IanBenzMaxim 0:33d4e66780c0 207 sha_writeResult(reverse, digest, H32);
IanBenzMaxim 0:33d4e66780c0 208
IanBenzMaxim 0:33d4e66780c0 209 #ifdef DEBUG_SHA
IanBenzMaxim 0:33d4e66780c0 210 dprintf("\nSHA-256 Result:\n");
IanBenzMaxim 0:33d4e66780c0 211 for (i = 0; i < 32; i++)
IanBenzMaxim 0:33d4e66780c0 212 dprintf("%02X ",digest[i]);
IanBenzMaxim 0:33d4e66780c0 213 dprintf("\n");
IanBenzMaxim 0:33d4e66780c0 214 #endif
IanBenzMaxim 0:33d4e66780c0 215 }
IanBenzMaxim 0:33d4e66780c0 216
IanBenzMaxim 0:33d4e66780c0 217 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 218 // ------ Internal utility functions to support SHA-256 calculation
IanBenzMaxim 0:33d4e66780c0 219 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 220
IanBenzMaxim 0:33d4e66780c0 221 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 222 /// @internal
IanBenzMaxim 0:33d4e66780c0 223 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 224 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 225 //
IanBenzMaxim 0:33d4e66780c0 226 static ulong sha_ch(ulong x, ulong y, ulong z)
IanBenzMaxim 0:33d4e66780c0 227 {
IanBenzMaxim 0:33d4e66780c0 228 return (x & y) ^ ((~x) & z);
IanBenzMaxim 0:33d4e66780c0 229 }
IanBenzMaxim 0:33d4e66780c0 230
IanBenzMaxim 0:33d4e66780c0 231 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 232 /// @internal
IanBenzMaxim 0:33d4e66780c0 233 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 234 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 235 //
IanBenzMaxim 0:33d4e66780c0 236 static ulong sha_maj(ulong x, ulong y, ulong z)
IanBenzMaxim 0:33d4e66780c0 237 {
IanBenzMaxim 0:33d4e66780c0 238 ulong temp = x & y;
IanBenzMaxim 0:33d4e66780c0 239 temp ^= (x & z);
IanBenzMaxim 0:33d4e66780c0 240 temp ^= (y & z);
IanBenzMaxim 0:33d4e66780c0 241 return temp; //(x & y) ^ (x & z) ^ (y & z);
IanBenzMaxim 0:33d4e66780c0 242 }
IanBenzMaxim 0:33d4e66780c0 243
IanBenzMaxim 0:33d4e66780c0 244 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 245 /// @internal
IanBenzMaxim 0:33d4e66780c0 246 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 247 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 248 //
IanBenzMaxim 0:33d4e66780c0 249 static ulong sha_rotr_32(ulong val, ushort r)
IanBenzMaxim 0:33d4e66780c0 250 {
IanBenzMaxim 0:33d4e66780c0 251 val = val & 0xFFFFFFFFL;
IanBenzMaxim 0:33d4e66780c0 252 return ((val >> r) | (val << (32 - r))) & 0xFFFFFFFFL;
IanBenzMaxim 0:33d4e66780c0 253 }
IanBenzMaxim 0:33d4e66780c0 254
IanBenzMaxim 0:33d4e66780c0 255 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 256 /// @internal
IanBenzMaxim 0:33d4e66780c0 257 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 258 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 259 //
IanBenzMaxim 0:33d4e66780c0 260 static ulong sha_shr_32(ulong val, ushort r)
IanBenzMaxim 0:33d4e66780c0 261 {
IanBenzMaxim 0:33d4e66780c0 262 val = val & 0xFFFFFFFFL;
IanBenzMaxim 0:33d4e66780c0 263 return val >> r;
IanBenzMaxim 0:33d4e66780c0 264 }
IanBenzMaxim 0:33d4e66780c0 265
IanBenzMaxim 0:33d4e66780c0 266 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 267 /// @internal
IanBenzMaxim 0:33d4e66780c0 268 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 269 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 270 //
IanBenzMaxim 0:33d4e66780c0 271 static ulong sha_bigsigma256_0(ulong x)
IanBenzMaxim 0:33d4e66780c0 272 {
IanBenzMaxim 0:33d4e66780c0 273 return sha_rotr_32(x,2) ^ sha_rotr_32(x,13) ^ sha_rotr_32(x,22);
IanBenzMaxim 0:33d4e66780c0 274 }
IanBenzMaxim 0:33d4e66780c0 275
IanBenzMaxim 0:33d4e66780c0 276 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 277 /// @internal
IanBenzMaxim 0:33d4e66780c0 278 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 279 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 280 //
IanBenzMaxim 0:33d4e66780c0 281 static ulong sha_bigsigma256_1(ulong x)
IanBenzMaxim 0:33d4e66780c0 282 {
IanBenzMaxim 0:33d4e66780c0 283 return sha_rotr_32(x,6) ^ sha_rotr_32(x,11) ^ sha_rotr_32(x,25);
IanBenzMaxim 0:33d4e66780c0 284 }
IanBenzMaxim 0:33d4e66780c0 285
IanBenzMaxim 0:33d4e66780c0 286 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 287 /// @internal
IanBenzMaxim 0:33d4e66780c0 288 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 289 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 290 //
IanBenzMaxim 0:33d4e66780c0 291 static ulong sha_littlesigma256_0(ulong x)
IanBenzMaxim 0:33d4e66780c0 292 {
IanBenzMaxim 0:33d4e66780c0 293 return sha_rotr_32(x,7) ^ sha_rotr_32(x,18) ^ sha_shr_32(x,3);
IanBenzMaxim 0:33d4e66780c0 294 }
IanBenzMaxim 0:33d4e66780c0 295
IanBenzMaxim 0:33d4e66780c0 296 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 297 /// @internal
IanBenzMaxim 0:33d4e66780c0 298 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 299 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 300 //
IanBenzMaxim 0:33d4e66780c0 301 static ulong sha_littlesigma256_1(ulong x)
IanBenzMaxim 0:33d4e66780c0 302 {
IanBenzMaxim 0:33d4e66780c0 303 return sha_rotr_32(x,17) ^ sha_rotr_32(x,19) ^ sha_shr_32(x,10);
IanBenzMaxim 0:33d4e66780c0 304 }
IanBenzMaxim 0:33d4e66780c0 305
IanBenzMaxim 0:33d4e66780c0 306 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 307 /// @internal
IanBenzMaxim 0:33d4e66780c0 308 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 309 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 310 //
IanBenzMaxim 0:33d4e66780c0 311 static void sha_copy32(const ulong* p1, ulong* p2, ushort length)
IanBenzMaxim 0:33d4e66780c0 312 {
IanBenzMaxim 0:33d4e66780c0 313 while (length > 0)
IanBenzMaxim 0:33d4e66780c0 314 {
IanBenzMaxim 0:33d4e66780c0 315 *p2++ = *p1++;
IanBenzMaxim 0:33d4e66780c0 316 length--;
IanBenzMaxim 0:33d4e66780c0 317 }
IanBenzMaxim 0:33d4e66780c0 318 }
IanBenzMaxim 0:33d4e66780c0 319
IanBenzMaxim 0:33d4e66780c0 320 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 321 /// @internal
IanBenzMaxim 0:33d4e66780c0 322 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 323 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 324 //
IanBenzMaxim 0:33d4e66780c0 325 static void sha_copyWordsToBytes32(const ulong* input, uchar* output, ushort numwords)
IanBenzMaxim 0:33d4e66780c0 326 {
IanBenzMaxim 0:33d4e66780c0 327 ulong temp;
IanBenzMaxim 0:33d4e66780c0 328 ushort i;
IanBenzMaxim 0:33d4e66780c0 329
IanBenzMaxim 0:33d4e66780c0 330 for (i=0;i<numwords;i++)
IanBenzMaxim 0:33d4e66780c0 331 {
IanBenzMaxim 0:33d4e66780c0 332 temp = *input++;
IanBenzMaxim 0:33d4e66780c0 333 *output++ = (uchar)(temp >> 24);
IanBenzMaxim 0:33d4e66780c0 334 *output++ = (uchar)(temp >> 16);
IanBenzMaxim 0:33d4e66780c0 335 *output++ = (uchar)(temp >> 8);
IanBenzMaxim 0:33d4e66780c0 336 *output++ = (uchar)(temp);
IanBenzMaxim 0:33d4e66780c0 337 }
IanBenzMaxim 0:33d4e66780c0 338 }
IanBenzMaxim 0:33d4e66780c0 339
IanBenzMaxim 0:33d4e66780c0 340 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 341 /// @internal
IanBenzMaxim 0:33d4e66780c0 342 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 343 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 344 //
IanBenzMaxim 0:33d4e66780c0 345 static void sha_writeResult(ushort reverse, uchar* outpointer, const ulong* H32)
IanBenzMaxim 0:33d4e66780c0 346 {
IanBenzMaxim 0:33d4e66780c0 347 int i;
IanBenzMaxim 0:33d4e66780c0 348 uchar tmp;
IanBenzMaxim 0:33d4e66780c0 349
IanBenzMaxim 0:33d4e66780c0 350 sha_copyWordsToBytes32(H32, outpointer, 8);
IanBenzMaxim 0:33d4e66780c0 351
IanBenzMaxim 0:33d4e66780c0 352 if (reverse)
IanBenzMaxim 0:33d4e66780c0 353 {
IanBenzMaxim 0:33d4e66780c0 354 for (i = 0; i < 16; i++)
IanBenzMaxim 0:33d4e66780c0 355 {
IanBenzMaxim 0:33d4e66780c0 356 tmp = outpointer[i];
IanBenzMaxim 0:33d4e66780c0 357 outpointer[i] = outpointer[31-i];
IanBenzMaxim 0:33d4e66780c0 358 outpointer[31-i] = tmp;
IanBenzMaxim 0:33d4e66780c0 359 }
IanBenzMaxim 0:33d4e66780c0 360 }
IanBenzMaxim 0:33d4e66780c0 361
IanBenzMaxim 0:33d4e66780c0 362 }
IanBenzMaxim 0:33d4e66780c0 363
IanBenzMaxim 0:33d4e66780c0 364 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 365 /// @internal
IanBenzMaxim 0:33d4e66780c0 366 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 367 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 368 //
IanBenzMaxim 0:33d4e66780c0 369 static ulong sha_getW(int index, ulong* W32)
IanBenzMaxim 0:33d4e66780c0 370 {
IanBenzMaxim 0:33d4e66780c0 371 ulong newW;
IanBenzMaxim 0:33d4e66780c0 372 if (index < 16)
IanBenzMaxim 0:33d4e66780c0 373 {
IanBenzMaxim 0:33d4e66780c0 374 return W32[index];
IanBenzMaxim 0:33d4e66780c0 375 }
IanBenzMaxim 0:33d4e66780c0 376
IanBenzMaxim 0:33d4e66780c0 377 newW = sha_littlesigma256_1(W32[(index-2)&0x0f]) +
IanBenzMaxim 0:33d4e66780c0 378 W32[(index-7)&0x0f] +
IanBenzMaxim 0:33d4e66780c0 379 sha_littlesigma256_0(W32[(index-15)&0x0f]) +
IanBenzMaxim 0:33d4e66780c0 380 W32[(index-16)&0x0f];
IanBenzMaxim 0:33d4e66780c0 381 W32[index & 0x0f] = newW & 0xFFFFFFFFL; // just in case...
IanBenzMaxim 0:33d4e66780c0 382
IanBenzMaxim 0:33d4e66780c0 383 return newW;
IanBenzMaxim 0:33d4e66780c0 384 }
IanBenzMaxim 0:33d4e66780c0 385
IanBenzMaxim 0:33d4e66780c0 386 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 387 /// @internal
IanBenzMaxim 0:33d4e66780c0 388 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 389 /// Prepair the block for hashing
IanBenzMaxim 0:33d4e66780c0 390 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 391 //
IanBenzMaxim 0:33d4e66780c0 392 static void sha_prepareSchedule(const uchar* message, ulong* W32)
IanBenzMaxim 0:33d4e66780c0 393 {
IanBenzMaxim 0:33d4e66780c0 394 // we need to copy the initial message into the 16 W registers
IanBenzMaxim 0:33d4e66780c0 395 ushort i,j;
IanBenzMaxim 0:33d4e66780c0 396 ulong temp;
IanBenzMaxim 0:33d4e66780c0 397 for (i = 0; i < 16; i++)
IanBenzMaxim 0:33d4e66780c0 398 {
IanBenzMaxim 0:33d4e66780c0 399 temp = 0;
IanBenzMaxim 0:33d4e66780c0 400 for (j = 0; j < 4;j++)
IanBenzMaxim 0:33d4e66780c0 401 {
IanBenzMaxim 0:33d4e66780c0 402 temp = temp << 8;
IanBenzMaxim 0:33d4e66780c0 403 temp = temp | (*message & 0xff);
IanBenzMaxim 0:33d4e66780c0 404 message++;
IanBenzMaxim 0:33d4e66780c0 405 }
IanBenzMaxim 0:33d4e66780c0 406
IanBenzMaxim 0:33d4e66780c0 407 W32[i] = temp;
IanBenzMaxim 0:33d4e66780c0 408 }
IanBenzMaxim 0:33d4e66780c0 409 }
IanBenzMaxim 0:33d4e66780c0 410
IanBenzMaxim 0:33d4e66780c0 411 //-----------------------------------------------------------------------------
IanBenzMaxim 0:33d4e66780c0 412 /// @internal
IanBenzMaxim 0:33d4e66780c0 413 /// SHA-256 support function
IanBenzMaxim 0:33d4e66780c0 414 /// Hash a single block of data.
IanBenzMaxim 0:33d4e66780c0 415 /// @endinternal
IanBenzMaxim 0:33d4e66780c0 416 //
IanBenzMaxim 0:33d4e66780c0 417 static void sha256_hashblock(const uchar* message, ushort lastblock, ulong* H32)
IanBenzMaxim 0:33d4e66780c0 418 {
IanBenzMaxim 0:33d4e66780c0 419 ushort sha1counter = 0;
IanBenzMaxim 0:33d4e66780c0 420 ushort sha1functionselect = 0;
IanBenzMaxim 0:33d4e66780c0 421 ushort i;
IanBenzMaxim 0:33d4e66780c0 422 ulong nodeT1, nodeT2;
IanBenzMaxim 0:33d4e66780c0 423
IanBenzMaxim 0:33d4e66780c0 424 ulong Wt, Kt;
IanBenzMaxim 0:33d4e66780c0 425
IanBenzMaxim 0:33d4e66780c0 426 ulong a32, b32, c32, d32, e32, f32, g32, h32; // SHA working variables
IanBenzMaxim 0:33d4e66780c0 427 ulong W32[16]; // SHA message schedule
IanBenzMaxim 0:33d4e66780c0 428
IanBenzMaxim 0:33d4e66780c0 429 // chunk the original message into the working schedule
IanBenzMaxim 0:33d4e66780c0 430 sha_prepareSchedule(message, W32);
IanBenzMaxim 0:33d4e66780c0 431
IanBenzMaxim 0:33d4e66780c0 432 a32 = H32[0];
IanBenzMaxim 0:33d4e66780c0 433 b32 = H32[1];
IanBenzMaxim 0:33d4e66780c0 434 c32 = H32[2];
IanBenzMaxim 0:33d4e66780c0 435 d32 = H32[3];
IanBenzMaxim 0:33d4e66780c0 436 e32 = H32[4];
IanBenzMaxim 0:33d4e66780c0 437 f32 = H32[5];
IanBenzMaxim 0:33d4e66780c0 438 g32 = H32[6];
IanBenzMaxim 0:33d4e66780c0 439 h32 = H32[7];
IanBenzMaxim 0:33d4e66780c0 440
IanBenzMaxim 0:33d4e66780c0 441 // rounds
IanBenzMaxim 0:33d4e66780c0 442 for (i = 0; i < 64; i++)
IanBenzMaxim 0:33d4e66780c0 443 {
IanBenzMaxim 0:33d4e66780c0 444 Wt = sha_getW(i, W32);
IanBenzMaxim 0:33d4e66780c0 445 Kt = SHA_CONSTANTS[i];
IanBenzMaxim 0:33d4e66780c0 446
IanBenzMaxim 0:33d4e66780c0 447 nodeT1 = (h32 + sha_bigsigma256_1(e32) + sha_ch(e32,f32,g32) + Kt + Wt); // & 0xFFFFFFFFL;
IanBenzMaxim 0:33d4e66780c0 448 nodeT2 = (sha_bigsigma256_0(a32) + sha_maj(a32,b32,c32)); // & 0xFFFFFFFFL;
IanBenzMaxim 0:33d4e66780c0 449 h32 = g32;
IanBenzMaxim 0:33d4e66780c0 450 g32 = f32;
IanBenzMaxim 0:33d4e66780c0 451 f32 = e32;
IanBenzMaxim 0:33d4e66780c0 452 e32 = d32 + nodeT1;
IanBenzMaxim 0:33d4e66780c0 453 d32 = c32;
IanBenzMaxim 0:33d4e66780c0 454 c32 = b32;
IanBenzMaxim 0:33d4e66780c0 455 b32 = a32;
IanBenzMaxim 0:33d4e66780c0 456 a32 = nodeT1 + nodeT2;
IanBenzMaxim 0:33d4e66780c0 457
IanBenzMaxim 0:33d4e66780c0 458 sha1counter++;
IanBenzMaxim 0:33d4e66780c0 459 if (sha1counter==20)
IanBenzMaxim 0:33d4e66780c0 460 {
IanBenzMaxim 0:33d4e66780c0 461 sha1functionselect++;
IanBenzMaxim 0:33d4e66780c0 462 sha1counter = 0;
IanBenzMaxim 0:33d4e66780c0 463 }
IanBenzMaxim 0:33d4e66780c0 464
IanBenzMaxim 0:33d4e66780c0 465 }
IanBenzMaxim 0:33d4e66780c0 466
IanBenzMaxim 0:33d4e66780c0 467 if (!lastblock)
IanBenzMaxim 0:33d4e66780c0 468 {
IanBenzMaxim 0:33d4e66780c0 469 // now fix up our H array
IanBenzMaxim 0:33d4e66780c0 470 H32[0] += a32;
IanBenzMaxim 0:33d4e66780c0 471 H32[1] += b32;
IanBenzMaxim 0:33d4e66780c0 472 H32[2] += c32;
IanBenzMaxim 0:33d4e66780c0 473 H32[3] += d32;
IanBenzMaxim 0:33d4e66780c0 474 H32[4] += e32;
IanBenzMaxim 0:33d4e66780c0 475 H32[5] += f32;
IanBenzMaxim 0:33d4e66780c0 476 H32[6] += g32;
IanBenzMaxim 0:33d4e66780c0 477 H32[7] += h32;
IanBenzMaxim 0:33d4e66780c0 478 }
IanBenzMaxim 0:33d4e66780c0 479 else
IanBenzMaxim 0:33d4e66780c0 480 {
IanBenzMaxim 0:33d4e66780c0 481 // now fix up our H array
IanBenzMaxim 0:33d4e66780c0 482 H32[0] = a32;
IanBenzMaxim 0:33d4e66780c0 483 H32[1] = b32;
IanBenzMaxim 0:33d4e66780c0 484 H32[2] = c32;
IanBenzMaxim 0:33d4e66780c0 485 H32[3] = d32;
IanBenzMaxim 0:33d4e66780c0 486 H32[4] = e32;
IanBenzMaxim 0:33d4e66780c0 487 H32[5] = f32;
IanBenzMaxim 0:33d4e66780c0 488 H32[6] = g32;
IanBenzMaxim 0:33d4e66780c0 489 H32[7] = h32;
IanBenzMaxim 0:33d4e66780c0 490 }
IanBenzMaxim 0:33d4e66780c0 491 }