Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3
XinZhangMS 0:f7f1f0d76dd6 4 /**************************** sha1.c ****************************/
XinZhangMS 0:f7f1f0d76dd6 5 /******************** See RFC 4634 for details ******************/
XinZhangMS 0:f7f1f0d76dd6 6 /*
XinZhangMS 0:f7f1f0d76dd6 7 * Description:
XinZhangMS 0:f7f1f0d76dd6 8 * This file implements the Secure Hash Signature Standard
XinZhangMS 0:f7f1f0d76dd6 9 * algorithms as defined in the National Institute of Standards
XinZhangMS 0:f7f1f0d76dd6 10 * and Technology Federal Information Processing Standards
XinZhangMS 0:f7f1f0d76dd6 11 * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
XinZhangMS 0:f7f1f0d76dd6 12 * published on August 1, 2002, and the FIPS PUB 180-2 Change
XinZhangMS 0:f7f1f0d76dd6 13 * Notice published on February 28, 2004.
XinZhangMS 0:f7f1f0d76dd6 14 *
XinZhangMS 0:f7f1f0d76dd6 15 * A combined document showing all algorithms is available at
XinZhangMS 0:f7f1f0d76dd6 16 * http://csrc.nist.gov/publications/fips/
XinZhangMS 0:f7f1f0d76dd6 17 * fips180-2/fips180-2withchangenotice.pdf
XinZhangMS 0:f7f1f0d76dd6 18 *
XinZhangMS 0:f7f1f0d76dd6 19 * The SHA-1 algorithm produces a 160-bit message digest for a
XinZhangMS 0:f7f1f0d76dd6 20 * given data stream. It should take about 2**n steps to find a
XinZhangMS 0:f7f1f0d76dd6 21 * message with the same digest as a given message and
XinZhangMS 0:f7f1f0d76dd6 22 * 2**(n/2) to find any two messages with the same digest,
XinZhangMS 0:f7f1f0d76dd6 23 * when n is the digest size in bits. Therefore, this
XinZhangMS 0:f7f1f0d76dd6 24 * algorithm can serve as a means of providing a
XinZhangMS 0:f7f1f0d76dd6 25 * "fingerprint" for a message.
XinZhangMS 0:f7f1f0d76dd6 26 *
XinZhangMS 0:f7f1f0d76dd6 27 * Portability Issues:
XinZhangMS 0:f7f1f0d76dd6 28 * SHA-1 is defined in terms of 32-bit "words". This code
XinZhangMS 0:f7f1f0d76dd6 29 * uses <stdint.h> (included via "sha.h") to define 32 and 8
XinZhangMS 0:f7f1f0d76dd6 30 * bit unsigned integer types. If your C compiler does not
XinZhangMS 0:f7f1f0d76dd6 31 * support 32 bit unsigned integers, this code is not
XinZhangMS 0:f7f1f0d76dd6 32 * appropriate.
XinZhangMS 0:f7f1f0d76dd6 33 *
XinZhangMS 0:f7f1f0d76dd6 34 * Caveats:
XinZhangMS 0:f7f1f0d76dd6 35 * SHA-1 is designed to work with messages less than 2^64 bits
XinZhangMS 0:f7f1f0d76dd6 36 * long. This implementation uses SHA1Input() to hash the bits
XinZhangMS 0:f7f1f0d76dd6 37 * that are a multiple of the size of an 8-bit character, and then
XinZhangMS 0:f7f1f0d76dd6 38 * uses SHA1FinalBits() to hash the final few bits of the input.
XinZhangMS 0:f7f1f0d76dd6 39 */
XinZhangMS 0:f7f1f0d76dd6 40
XinZhangMS 0:f7f1f0d76dd6 41 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 42 #include "azure_c_shared_utility/gballoc.h"
XinZhangMS 0:f7f1f0d76dd6 43
XinZhangMS 0:f7f1f0d76dd6 44 #include "azure_c_shared_utility/sha.h"
XinZhangMS 0:f7f1f0d76dd6 45 #include "azure_c_shared_utility/sha-private.h"
XinZhangMS 0:f7f1f0d76dd6 46
XinZhangMS 0:f7f1f0d76dd6 47 /*
XinZhangMS 0:f7f1f0d76dd6 48 * Define the SHA1 circular left shift macro
XinZhangMS 0:f7f1f0d76dd6 49 */
XinZhangMS 0:f7f1f0d76dd6 50 #define SHA1_ROTL(bits,word) \
XinZhangMS 0:f7f1f0d76dd6 51 (((word) << (bits)) | ((word) >> (32-(bits))))
XinZhangMS 0:f7f1f0d76dd6 52
XinZhangMS 0:f7f1f0d76dd6 53 /*
XinZhangMS 0:f7f1f0d76dd6 54 * add "length" to the length
XinZhangMS 0:f7f1f0d76dd6 55 */
XinZhangMS 0:f7f1f0d76dd6 56 #define SHA1AddLength(context, length) \
XinZhangMS 0:f7f1f0d76dd6 57 (addTemp = (context)->Length_Low, \
XinZhangMS 0:f7f1f0d76dd6 58 (context)->Corrupted = \
XinZhangMS 0:f7f1f0d76dd6 59 (((context)->Length_Low += (length)) < addTemp) && \
XinZhangMS 0:f7f1f0d76dd6 60 (++(context)->Length_High == 0) ? 1 : 0)
XinZhangMS 0:f7f1f0d76dd6 61
XinZhangMS 0:f7f1f0d76dd6 62 /* Local Function Prototypes */
XinZhangMS 0:f7f1f0d76dd6 63 static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
XinZhangMS 0:f7f1f0d76dd6 64 static void SHA1PadMessage(SHA1Context *, uint8_t Pad_Byte);
XinZhangMS 0:f7f1f0d76dd6 65 static void SHA1ProcessMessageBlock(SHA1Context *);
XinZhangMS 0:f7f1f0d76dd6 66
XinZhangMS 0:f7f1f0d76dd6 67 /*
XinZhangMS 0:f7f1f0d76dd6 68 * SHA1Reset
XinZhangMS 0:f7f1f0d76dd6 69 *
XinZhangMS 0:f7f1f0d76dd6 70 * Description:
XinZhangMS 0:f7f1f0d76dd6 71 * This function will initialize the SHA1Context in preparation
XinZhangMS 0:f7f1f0d76dd6 72 * for computing a new SHA1 message digest.
XinZhangMS 0:f7f1f0d76dd6 73 *
XinZhangMS 0:f7f1f0d76dd6 74 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 75 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 76 * The context to reset.
XinZhangMS 0:f7f1f0d76dd6 77 *
XinZhangMS 0:f7f1f0d76dd6 78 * Returns:
XinZhangMS 0:f7f1f0d76dd6 79 * sha Error Code.
XinZhangMS 0:f7f1f0d76dd6 80 *
XinZhangMS 0:f7f1f0d76dd6 81 */
XinZhangMS 0:f7f1f0d76dd6 82 int SHA1Reset(SHA1Context *context)
XinZhangMS 0:f7f1f0d76dd6 83 {
XinZhangMS 0:f7f1f0d76dd6 84 if (!context)
XinZhangMS 0:f7f1f0d76dd6 85 return shaNull;
XinZhangMS 0:f7f1f0d76dd6 86
XinZhangMS 0:f7f1f0d76dd6 87 context->Length_Low = 0;
XinZhangMS 0:f7f1f0d76dd6 88 context->Length_High = 0;
XinZhangMS 0:f7f1f0d76dd6 89 context->Message_Block_Index = 0;
XinZhangMS 0:f7f1f0d76dd6 90
XinZhangMS 0:f7f1f0d76dd6 91
XinZhangMS 0:f7f1f0d76dd6 92 /* Initial Hash Values: FIPS-180-2 section 5.3.1 */
XinZhangMS 0:f7f1f0d76dd6 93 context->Intermediate_Hash[0] = 0x67452301;
XinZhangMS 0:f7f1f0d76dd6 94 context->Intermediate_Hash[1] = 0xEFCDAB89;
XinZhangMS 0:f7f1f0d76dd6 95 context->Intermediate_Hash[2] = 0x98BADCFE;
XinZhangMS 0:f7f1f0d76dd6 96 context->Intermediate_Hash[3] = 0x10325476;
XinZhangMS 0:f7f1f0d76dd6 97 context->Intermediate_Hash[4] = 0xC3D2E1F0;
XinZhangMS 0:f7f1f0d76dd6 98
XinZhangMS 0:f7f1f0d76dd6 99 context->Computed = 0;
XinZhangMS 0:f7f1f0d76dd6 100 context->Corrupted = 0;
XinZhangMS 0:f7f1f0d76dd6 101
XinZhangMS 0:f7f1f0d76dd6 102 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 103 }
XinZhangMS 0:f7f1f0d76dd6 104
XinZhangMS 0:f7f1f0d76dd6 105 /*
XinZhangMS 0:f7f1f0d76dd6 106 * SHA1Input
XinZhangMS 0:f7f1f0d76dd6 107 *
XinZhangMS 0:f7f1f0d76dd6 108 * Description:
XinZhangMS 0:f7f1f0d76dd6 109 * This function accepts an array of octets as the next portion
XinZhangMS 0:f7f1f0d76dd6 110 * of the message.
XinZhangMS 0:f7f1f0d76dd6 111 *
XinZhangMS 0:f7f1f0d76dd6 112 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 113 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 114 * The SHA context to update
XinZhangMS 0:f7f1f0d76dd6 115 * message_array: [in]
XinZhangMS 0:f7f1f0d76dd6 116 * An array of characters representing the next portion of
XinZhangMS 0:f7f1f0d76dd6 117 * the message.
XinZhangMS 0:f7f1f0d76dd6 118 * length: [in]
XinZhangMS 0:f7f1f0d76dd6 119 * The length of the message in message_array
XinZhangMS 0:f7f1f0d76dd6 120 *
XinZhangMS 0:f7f1f0d76dd6 121 * Returns:
XinZhangMS 0:f7f1f0d76dd6 122 * sha Error Code.
XinZhangMS 0:f7f1f0d76dd6 123 *
XinZhangMS 0:f7f1f0d76dd6 124 */
XinZhangMS 0:f7f1f0d76dd6 125 int SHA1Input(SHA1Context *context,
XinZhangMS 0:f7f1f0d76dd6 126 const uint8_t *message_array, unsigned length)
XinZhangMS 0:f7f1f0d76dd6 127 {
XinZhangMS 0:f7f1f0d76dd6 128 uint32_t addTemp;
XinZhangMS 0:f7f1f0d76dd6 129 if (!length)
XinZhangMS 0:f7f1f0d76dd6 130 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 131
XinZhangMS 0:f7f1f0d76dd6 132 if (!context || !message_array)
XinZhangMS 0:f7f1f0d76dd6 133 return shaNull;
XinZhangMS 0:f7f1f0d76dd6 134
XinZhangMS 0:f7f1f0d76dd6 135 if (context->Computed) {
XinZhangMS 0:f7f1f0d76dd6 136 context->Corrupted = shaStateError;
XinZhangMS 0:f7f1f0d76dd6 137 return shaStateError;
XinZhangMS 0:f7f1f0d76dd6 138 }
XinZhangMS 0:f7f1f0d76dd6 139
XinZhangMS 0:f7f1f0d76dd6 140 if (context->Corrupted)
XinZhangMS 0:f7f1f0d76dd6 141 return context->Corrupted;
XinZhangMS 0:f7f1f0d76dd6 142
XinZhangMS 0:f7f1f0d76dd6 143 while (length-- && !context->Corrupted) {
XinZhangMS 0:f7f1f0d76dd6 144 context->Message_Block[context->Message_Block_Index++] =
XinZhangMS 0:f7f1f0d76dd6 145 (*message_array & 0xFF);
XinZhangMS 0:f7f1f0d76dd6 146
XinZhangMS 0:f7f1f0d76dd6 147 if (!SHA1AddLength(context, 8) &&
XinZhangMS 0:f7f1f0d76dd6 148 (context->Message_Block_Index == SHA1_Message_Block_Size))
XinZhangMS 0:f7f1f0d76dd6 149 SHA1ProcessMessageBlock(context);
XinZhangMS 0:f7f1f0d76dd6 150
XinZhangMS 0:f7f1f0d76dd6 151 message_array++;
XinZhangMS 0:f7f1f0d76dd6 152 }
XinZhangMS 0:f7f1f0d76dd6 153
XinZhangMS 0:f7f1f0d76dd6 154 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 155 }
XinZhangMS 0:f7f1f0d76dd6 156
XinZhangMS 0:f7f1f0d76dd6 157 /*
XinZhangMS 0:f7f1f0d76dd6 158 * SHA1FinalBits
XinZhangMS 0:f7f1f0d76dd6 159 *
XinZhangMS 0:f7f1f0d76dd6 160 * Description:
XinZhangMS 0:f7f1f0d76dd6 161 * This function will add in any final bits of the message.
XinZhangMS 0:f7f1f0d76dd6 162 *
XinZhangMS 0:f7f1f0d76dd6 163 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 164 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 165 * The SHA context to update
XinZhangMS 0:f7f1f0d76dd6 166 * message_bits: [in]
XinZhangMS 0:f7f1f0d76dd6 167 * The final bits of the message, in the upper portion of the
XinZhangMS 0:f7f1f0d76dd6 168 * byte. (Use 0b###00000 instead of 0b00000### to input the
XinZhangMS 0:f7f1f0d76dd6 169 * three bits ###.)
XinZhangMS 0:f7f1f0d76dd6 170 * length: [in]
XinZhangMS 0:f7f1f0d76dd6 171 * The number of bits in message_bits, between 1 and 7.
XinZhangMS 0:f7f1f0d76dd6 172 *
XinZhangMS 0:f7f1f0d76dd6 173 * Returns:
XinZhangMS 0:f7f1f0d76dd6 174 * sha Error Code.
XinZhangMS 0:f7f1f0d76dd6 175 */
XinZhangMS 0:f7f1f0d76dd6 176 int SHA1FinalBits(SHA1Context *context, const uint8_t message_bits,
XinZhangMS 0:f7f1f0d76dd6 177 unsigned int length)
XinZhangMS 0:f7f1f0d76dd6 178 {
XinZhangMS 0:f7f1f0d76dd6 179 uint32_t addTemp;
XinZhangMS 0:f7f1f0d76dd6 180
XinZhangMS 0:f7f1f0d76dd6 181 uint8_t masks[8] = {
XinZhangMS 0:f7f1f0d76dd6 182 /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
XinZhangMS 0:f7f1f0d76dd6 183 /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
XinZhangMS 0:f7f1f0d76dd6 184 /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
XinZhangMS 0:f7f1f0d76dd6 185 /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
XinZhangMS 0:f7f1f0d76dd6 186 };
XinZhangMS 0:f7f1f0d76dd6 187 uint8_t markbit[8] = {
XinZhangMS 0:f7f1f0d76dd6 188 /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
XinZhangMS 0:f7f1f0d76dd6 189 /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
XinZhangMS 0:f7f1f0d76dd6 190 /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
XinZhangMS 0:f7f1f0d76dd6 191 /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
XinZhangMS 0:f7f1f0d76dd6 192 };
XinZhangMS 0:f7f1f0d76dd6 193
XinZhangMS 0:f7f1f0d76dd6 194 if (!length)
XinZhangMS 0:f7f1f0d76dd6 195 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 196
XinZhangMS 0:f7f1f0d76dd6 197 if (!context)
XinZhangMS 0:f7f1f0d76dd6 198 return shaNull;
XinZhangMS 0:f7f1f0d76dd6 199
XinZhangMS 0:f7f1f0d76dd6 200 if (context->Computed || (length >= 8) || (length == 0)) {
XinZhangMS 0:f7f1f0d76dd6 201 context->Corrupted = shaStateError;
XinZhangMS 0:f7f1f0d76dd6 202 return shaStateError;
XinZhangMS 0:f7f1f0d76dd6 203 }
XinZhangMS 0:f7f1f0d76dd6 204
XinZhangMS 0:f7f1f0d76dd6 205 if (context->Corrupted)
XinZhangMS 0:f7f1f0d76dd6 206 return context->Corrupted;
XinZhangMS 0:f7f1f0d76dd6 207
XinZhangMS 0:f7f1f0d76dd6 208 SHA1AddLength(context, length);
XinZhangMS 0:f7f1f0d76dd6 209 SHA1Finalize(context,
XinZhangMS 0:f7f1f0d76dd6 210 (uint8_t)((message_bits & masks[length]) | markbit[length]));
XinZhangMS 0:f7f1f0d76dd6 211
XinZhangMS 0:f7f1f0d76dd6 212 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 213 }
XinZhangMS 0:f7f1f0d76dd6 214
XinZhangMS 0:f7f1f0d76dd6 215 /*
XinZhangMS 0:f7f1f0d76dd6 216 * SHA1Result
XinZhangMS 0:f7f1f0d76dd6 217 *
XinZhangMS 0:f7f1f0d76dd6 218 * Description:
XinZhangMS 0:f7f1f0d76dd6 219 * This function will return the 160-bit message digest into the
XinZhangMS 0:f7f1f0d76dd6 220 * Message_Digest array provided by the caller.
XinZhangMS 0:f7f1f0d76dd6 221 * NOTE: The first octet of hash is stored in the 0th element,
XinZhangMS 0:f7f1f0d76dd6 222 * the last octet of hash in the 19th element.
XinZhangMS 0:f7f1f0d76dd6 223 *
XinZhangMS 0:f7f1f0d76dd6 224 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 225 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 226 * The context to use to calculate the SHA-1 hash.
XinZhangMS 0:f7f1f0d76dd6 227 * Message_Digest: [out]
XinZhangMS 0:f7f1f0d76dd6 228 * Where the digest is returned.
XinZhangMS 0:f7f1f0d76dd6 229 *
XinZhangMS 0:f7f1f0d76dd6 230 * Returns:
XinZhangMS 0:f7f1f0d76dd6 231 * sha Error Code.
XinZhangMS 0:f7f1f0d76dd6 232 *
XinZhangMS 0:f7f1f0d76dd6 233 */
XinZhangMS 0:f7f1f0d76dd6 234 int SHA1Result(SHA1Context *context,
XinZhangMS 0:f7f1f0d76dd6 235 uint8_t Message_Digest[SHA1HashSize])
XinZhangMS 0:f7f1f0d76dd6 236 {
XinZhangMS 0:f7f1f0d76dd6 237 int i;
XinZhangMS 0:f7f1f0d76dd6 238
XinZhangMS 0:f7f1f0d76dd6 239 if (!context || !Message_Digest)
XinZhangMS 0:f7f1f0d76dd6 240 return shaNull;
XinZhangMS 0:f7f1f0d76dd6 241
XinZhangMS 0:f7f1f0d76dd6 242 if (context->Corrupted)
XinZhangMS 0:f7f1f0d76dd6 243 return context->Corrupted;
XinZhangMS 0:f7f1f0d76dd6 244
XinZhangMS 0:f7f1f0d76dd6 245 if (!context->Computed)
XinZhangMS 0:f7f1f0d76dd6 246 SHA1Finalize(context, 0x80);
XinZhangMS 0:f7f1f0d76dd6 247
XinZhangMS 0:f7f1f0d76dd6 248 for (i = 0; i < SHA1HashSize; ++i)
XinZhangMS 0:f7f1f0d76dd6 249 Message_Digest[i] = (uint8_t)(context->Intermediate_Hash[i >> 2]
XinZhangMS 0:f7f1f0d76dd6 250 >> 8 * (3 - (i & 0x03)));
XinZhangMS 0:f7f1f0d76dd6 251
XinZhangMS 0:f7f1f0d76dd6 252 return shaSuccess;
XinZhangMS 0:f7f1f0d76dd6 253 }
XinZhangMS 0:f7f1f0d76dd6 254
XinZhangMS 0:f7f1f0d76dd6 255 /*
XinZhangMS 0:f7f1f0d76dd6 256 * SHA1Finalize
XinZhangMS 0:f7f1f0d76dd6 257 *
XinZhangMS 0:f7f1f0d76dd6 258 * Description:
XinZhangMS 0:f7f1f0d76dd6 259 * This helper function finishes off the digest calculations.
XinZhangMS 0:f7f1f0d76dd6 260 *
XinZhangMS 0:f7f1f0d76dd6 261 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 262 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 263 * The SHA context to update
XinZhangMS 0:f7f1f0d76dd6 264 * Pad_Byte: [in]
XinZhangMS 0:f7f1f0d76dd6 265 * The last byte to add to the digest before the 0-padding
XinZhangMS 0:f7f1f0d76dd6 266 * and length. This will contain the last bits of the message
XinZhangMS 0:f7f1f0d76dd6 267 * followed by another single bit. If the message was an
XinZhangMS 0:f7f1f0d76dd6 268 * exact multiple of 8-bits long, Pad_Byte will be 0x80.
XinZhangMS 0:f7f1f0d76dd6 269 *
XinZhangMS 0:f7f1f0d76dd6 270 * Returns:
XinZhangMS 0:f7f1f0d76dd6 271 * sha Error Code.
XinZhangMS 0:f7f1f0d76dd6 272 *
XinZhangMS 0:f7f1f0d76dd6 273 */
XinZhangMS 0:f7f1f0d76dd6 274 static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
XinZhangMS 0:f7f1f0d76dd6 275 {
XinZhangMS 0:f7f1f0d76dd6 276 int i;
XinZhangMS 0:f7f1f0d76dd6 277 SHA1PadMessage(context, Pad_Byte);
XinZhangMS 0:f7f1f0d76dd6 278 /* message may be sensitive, clear it out */
XinZhangMS 0:f7f1f0d76dd6 279 for (i = 0; i < SHA1_Message_Block_Size; ++i)
XinZhangMS 0:f7f1f0d76dd6 280 context->Message_Block[i] = 0;
XinZhangMS 0:f7f1f0d76dd6 281 context->Length_Low = 0; /* and clear length */
XinZhangMS 0:f7f1f0d76dd6 282 context->Length_High = 0;
XinZhangMS 0:f7f1f0d76dd6 283 context->Computed = 1;
XinZhangMS 0:f7f1f0d76dd6 284 }
XinZhangMS 0:f7f1f0d76dd6 285
XinZhangMS 0:f7f1f0d76dd6 286 /*
XinZhangMS 0:f7f1f0d76dd6 287 * SHA1PadMessage
XinZhangMS 0:f7f1f0d76dd6 288 *
XinZhangMS 0:f7f1f0d76dd6 289 * Description:
XinZhangMS 0:f7f1f0d76dd6 290 * According to the standard, the message must be padded to an
XinZhangMS 0:f7f1f0d76dd6 291 * even 512 bits. The first padding bit must be a '1'. The last
XinZhangMS 0:f7f1f0d76dd6 292 * 64 bits represent the length of the original message. All bits
XinZhangMS 0:f7f1f0d76dd6 293 * in between should be 0. This helper function will pad the
XinZhangMS 0:f7f1f0d76dd6 294 * message according to those rules by filling the Message_Block
XinZhangMS 0:f7f1f0d76dd6 295 * array accordingly. When it returns, it can be assumed that the
XinZhangMS 0:f7f1f0d76dd6 296 * message digest has been computed.
XinZhangMS 0:f7f1f0d76dd6 297 *
XinZhangMS 0:f7f1f0d76dd6 298 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 299 * context: [in/out]
XinZhangMS 0:f7f1f0d76dd6 300 * The context to pad
XinZhangMS 0:f7f1f0d76dd6 301 * Pad_Byte: [in]
XinZhangMS 0:f7f1f0d76dd6 302 * The last byte to add to the digest before the 0-padding
XinZhangMS 0:f7f1f0d76dd6 303 * and length. This will contain the last bits of the message
XinZhangMS 0:f7f1f0d76dd6 304 * followed by another single bit. If the message was an
XinZhangMS 0:f7f1f0d76dd6 305 * exact multiple of 8-bits long, Pad_Byte will be 0x80.
XinZhangMS 0:f7f1f0d76dd6 306 *
XinZhangMS 0:f7f1f0d76dd6 307 * Returns:
XinZhangMS 0:f7f1f0d76dd6 308 * Nothing.
XinZhangMS 0:f7f1f0d76dd6 309 */
XinZhangMS 0:f7f1f0d76dd6 310 static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
XinZhangMS 0:f7f1f0d76dd6 311 {
XinZhangMS 0:f7f1f0d76dd6 312 /*
XinZhangMS 0:f7f1f0d76dd6 313 * Check to see if the current message block is too small to hold
XinZhangMS 0:f7f1f0d76dd6 314 * the initial padding bits and length. If so, we will pad the
XinZhangMS 0:f7f1f0d76dd6 315 * block, process it, and then continue padding into a second
XinZhangMS 0:f7f1f0d76dd6 316 * block.
XinZhangMS 0:f7f1f0d76dd6 317 */
XinZhangMS 0:f7f1f0d76dd6 318 if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
XinZhangMS 0:f7f1f0d76dd6 319 context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
XinZhangMS 0:f7f1f0d76dd6 320 while (context->Message_Block_Index < SHA1_Message_Block_Size)
XinZhangMS 0:f7f1f0d76dd6 321 context->Message_Block[context->Message_Block_Index++] = 0;
XinZhangMS 0:f7f1f0d76dd6 322
XinZhangMS 0:f7f1f0d76dd6 323 SHA1ProcessMessageBlock(context);
XinZhangMS 0:f7f1f0d76dd6 324 }
XinZhangMS 0:f7f1f0d76dd6 325 else
XinZhangMS 0:f7f1f0d76dd6 326 context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
XinZhangMS 0:f7f1f0d76dd6 327
XinZhangMS 0:f7f1f0d76dd6 328 while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
XinZhangMS 0:f7f1f0d76dd6 329 context->Message_Block[context->Message_Block_Index++] = 0;
XinZhangMS 0:f7f1f0d76dd6 330
XinZhangMS 0:f7f1f0d76dd6 331 /*
XinZhangMS 0:f7f1f0d76dd6 332 * Store the message length as the last 8 octets
XinZhangMS 0:f7f1f0d76dd6 333 */
XinZhangMS 0:f7f1f0d76dd6 334 context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
XinZhangMS 0:f7f1f0d76dd6 335 context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
XinZhangMS 0:f7f1f0d76dd6 336
XinZhangMS 0:f7f1f0d76dd6 337 context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
XinZhangMS 0:f7f1f0d76dd6 338 context->Message_Block[59] = (uint8_t)(context->Length_High);
XinZhangMS 0:f7f1f0d76dd6 339 context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
XinZhangMS 0:f7f1f0d76dd6 340 context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
XinZhangMS 0:f7f1f0d76dd6 341 context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
XinZhangMS 0:f7f1f0d76dd6 342 context->Message_Block[63] = (uint8_t)(context->Length_Low);
XinZhangMS 0:f7f1f0d76dd6 343
XinZhangMS 0:f7f1f0d76dd6 344 SHA1ProcessMessageBlock(context);
XinZhangMS 0:f7f1f0d76dd6 345 }
XinZhangMS 0:f7f1f0d76dd6 346
XinZhangMS 0:f7f1f0d76dd6 347 /*
XinZhangMS 0:f7f1f0d76dd6 348 * SHA1ProcessMessageBlock
XinZhangMS 0:f7f1f0d76dd6 349 *
XinZhangMS 0:f7f1f0d76dd6 350 * Description:
XinZhangMS 0:f7f1f0d76dd6 351 * This helper function will process the next 512 bits of the
XinZhangMS 0:f7f1f0d76dd6 352 * message stored in the Message_Block array.
XinZhangMS 0:f7f1f0d76dd6 353 *
XinZhangMS 0:f7f1f0d76dd6 354 * Parameters:
XinZhangMS 0:f7f1f0d76dd6 355 * None.
XinZhangMS 0:f7f1f0d76dd6 356 *
XinZhangMS 0:f7f1f0d76dd6 357 * Returns:
XinZhangMS 0:f7f1f0d76dd6 358 * Nothing.
XinZhangMS 0:f7f1f0d76dd6 359 *
XinZhangMS 0:f7f1f0d76dd6 360 * Comments:
XinZhangMS 0:f7f1f0d76dd6 361 * Many of the variable names in this code, especially the
XinZhangMS 0:f7f1f0d76dd6 362 * single character names, were used because those were the
XinZhangMS 0:f7f1f0d76dd6 363 * names used in the publication.
XinZhangMS 0:f7f1f0d76dd6 364 */
XinZhangMS 0:f7f1f0d76dd6 365 static void SHA1ProcessMessageBlock(SHA1Context *context)
XinZhangMS 0:f7f1f0d76dd6 366 {
XinZhangMS 0:f7f1f0d76dd6 367 /* Constants defined in FIPS-180-2, section 4.2.1 */
XinZhangMS 0:f7f1f0d76dd6 368 const uint32_t K[4] = {
XinZhangMS 0:f7f1f0d76dd6 369 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
XinZhangMS 0:f7f1f0d76dd6 370 };
XinZhangMS 0:f7f1f0d76dd6 371 int t; /* Loop counter */
XinZhangMS 0:f7f1f0d76dd6 372 uint32_t temp; /* Temporary word value */
XinZhangMS 0:f7f1f0d76dd6 373 uint32_t W[80]; /* Word sequence */
XinZhangMS 0:f7f1f0d76dd6 374 uint32_t A, B, C, D, E; /* Word buffers */
XinZhangMS 0:f7f1f0d76dd6 375
XinZhangMS 0:f7f1f0d76dd6 376 /*
XinZhangMS 0:f7f1f0d76dd6 377 * Initialize the first 16 words in the array W
XinZhangMS 0:f7f1f0d76dd6 378 */
XinZhangMS 0:f7f1f0d76dd6 379 for (t = 0; t < 16; t++) {
XinZhangMS 0:f7f1f0d76dd6 380 W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24;
XinZhangMS 0:f7f1f0d76dd6 381 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16;
XinZhangMS 0:f7f1f0d76dd6 382 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
XinZhangMS 0:f7f1f0d76dd6 383 W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
XinZhangMS 0:f7f1f0d76dd6 384 }
XinZhangMS 0:f7f1f0d76dd6 385
XinZhangMS 0:f7f1f0d76dd6 386 for (t = 16; t < 80; t++)
XinZhangMS 0:f7f1f0d76dd6 387 W[t] = SHA1_ROTL(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
XinZhangMS 0:f7f1f0d76dd6 388
XinZhangMS 0:f7f1f0d76dd6 389 A = context->Intermediate_Hash[0];
XinZhangMS 0:f7f1f0d76dd6 390 B = context->Intermediate_Hash[1];
XinZhangMS 0:f7f1f0d76dd6 391 C = context->Intermediate_Hash[2];
XinZhangMS 0:f7f1f0d76dd6 392 D = context->Intermediate_Hash[3];
XinZhangMS 0:f7f1f0d76dd6 393 E = context->Intermediate_Hash[4];
XinZhangMS 0:f7f1f0d76dd6 394
XinZhangMS 0:f7f1f0d76dd6 395 for (t = 0; t < 20; t++) {
XinZhangMS 0:f7f1f0d76dd6 396 temp = SHA1_ROTL(5, A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
XinZhangMS 0:f7f1f0d76dd6 397 E = D;
XinZhangMS 0:f7f1f0d76dd6 398 D = C;
XinZhangMS 0:f7f1f0d76dd6 399 C = SHA1_ROTL(30, B);
XinZhangMS 0:f7f1f0d76dd6 400 B = A;
XinZhangMS 0:f7f1f0d76dd6 401 A = temp;
XinZhangMS 0:f7f1f0d76dd6 402 }
XinZhangMS 0:f7f1f0d76dd6 403
XinZhangMS 0:f7f1f0d76dd6 404 for (t = 20; t < 40; t++) {
XinZhangMS 0:f7f1f0d76dd6 405 temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
XinZhangMS 0:f7f1f0d76dd6 406 E = D;
XinZhangMS 0:f7f1f0d76dd6 407 D = C;
XinZhangMS 0:f7f1f0d76dd6 408 C = SHA1_ROTL(30, B);
XinZhangMS 0:f7f1f0d76dd6 409 B = A;
XinZhangMS 0:f7f1f0d76dd6 410 A = temp;
XinZhangMS 0:f7f1f0d76dd6 411 }
XinZhangMS 0:f7f1f0d76dd6 412
XinZhangMS 0:f7f1f0d76dd6 413 for (t = 40; t < 60; t++) {
XinZhangMS 0:f7f1f0d76dd6 414 temp = SHA1_ROTL(5, A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
XinZhangMS 0:f7f1f0d76dd6 415 E = D;
XinZhangMS 0:f7f1f0d76dd6 416 D = C;
XinZhangMS 0:f7f1f0d76dd6 417 C = SHA1_ROTL(30, B);
XinZhangMS 0:f7f1f0d76dd6 418 B = A;
XinZhangMS 0:f7f1f0d76dd6 419 A = temp;
XinZhangMS 0:f7f1f0d76dd6 420 }
XinZhangMS 0:f7f1f0d76dd6 421
XinZhangMS 0:f7f1f0d76dd6 422 for (t = 60; t < 80; t++) {
XinZhangMS 0:f7f1f0d76dd6 423 temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
XinZhangMS 0:f7f1f0d76dd6 424 E = D;
XinZhangMS 0:f7f1f0d76dd6 425 D = C;
XinZhangMS 0:f7f1f0d76dd6 426 C = SHA1_ROTL(30, B);
XinZhangMS 0:f7f1f0d76dd6 427 B = A;
XinZhangMS 0:f7f1f0d76dd6 428 A = temp;
XinZhangMS 0:f7f1f0d76dd6 429 }
XinZhangMS 0:f7f1f0d76dd6 430
XinZhangMS 0:f7f1f0d76dd6 431 context->Intermediate_Hash[0] += A;
XinZhangMS 0:f7f1f0d76dd6 432 context->Intermediate_Hash[1] += B;
XinZhangMS 0:f7f1f0d76dd6 433 context->Intermediate_Hash[2] += C;
XinZhangMS 0:f7f1f0d76dd6 434
XinZhangMS 0:f7f1f0d76dd6 435 context->Intermediate_Hash[3] += D;
XinZhangMS 0:f7f1f0d76dd6 436 context->Intermediate_Hash[4] += E;
XinZhangMS 0:f7f1f0d76dd6 437
XinZhangMS 0:f7f1f0d76dd6 438 context->Message_Block_Index = 0;
XinZhangMS 0:f7f1f0d76dd6 439 }
XinZhangMS 0:f7f1f0d76dd6 440