This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

This library implements the following algorithms :

  • RC4
  • AES (AES-128, AES-192, AES-256)
  • DES
  • Triple DES (EDE)
  • MD2
  • MD4
  • MD5
  • SHA-1
  • SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)

The hash algorithms have been optimized for the mbed and you should get decent performance. However, I did not optimize the ciphers. Also, I did not test extensively these algorithms : it should work but you may find some bugs. Block ciphers support two modes : ECB and CBC.

Warning

If you are using SHA-384 or SHA-512, be aware that it produces large binary files and the compilation (using the online compiler) takes much longer to execute. It may happen that the compiler stops because it timed-out. In this case, just compile again and it should work.

Computing hash

You can compute the hash of some data in two different ways. The first one is the easiest, each hash algorithm has a static method that takes some data and compute the hash from it.

Computing hash using method 1

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2::computeHash(hash, (uint8_t*)msg, strlen(msg));
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

The second one is slightly slower (around 2-3% slower) but it allows you to compute the hash of some data in several steps (by calling update method). This is the method you should use if you need to compute the hash from a large source and you don't have enough memory to store it in a single buffer.

Computing hash using method 2

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2 h;
    h.update((uint8_t*)msg, strlen(msg));
    h.finalize(hash);
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

TODO

  • optimize ciphers
  • add doc
Committer:
feb11
Date:
Sat Sep 07 23:47:28 2013 +0000
Revision:
0:7a1237bd2d13
Child:
2:473bac39ae7c
initial import

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:7a1237bd2d13 1 #include "SHA2_32.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 0:7a1237bd2d13 3 #include <stdio.h>
feb11 0:7a1237bd2d13 4 #include <stdlib.h>
feb11 0:7a1237bd2d13 5
feb11 0:7a1237bd2d13 6 static const uint32_t K[] =
feb11 0:7a1237bd2d13 7 {
feb11 0:7a1237bd2d13 8 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
feb11 0:7a1237bd2d13 9 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
feb11 0:7a1237bd2d13 10 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
feb11 0:7a1237bd2d13 11 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
feb11 0:7a1237bd2d13 12 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
feb11 0:7a1237bd2d13 13 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
feb11 0:7a1237bd2d13 14 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
feb11 0:7a1237bd2d13 15 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
feb11 0:7a1237bd2d13 16 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
feb11 0:7a1237bd2d13 17 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
feb11 0:7a1237bd2d13 18 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
feb11 0:7a1237bd2d13 19 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
feb11 0:7a1237bd2d13 20 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
feb11 0:7a1237bd2d13 21 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
feb11 0:7a1237bd2d13 22 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
feb11 0:7a1237bd2d13 23 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
feb11 0:7a1237bd2d13 24 };
feb11 0:7a1237bd2d13 25
feb11 0:7a1237bd2d13 26 static uint32_t rotLeft(uint32_t w, uint8_t n)
feb11 0:7a1237bd2d13 27 {
feb11 0:7a1237bd2d13 28 return (w << n) | (w >> (32-n));
feb11 0:7a1237bd2d13 29 }
feb11 0:7a1237bd2d13 30
feb11 0:7a1237bd2d13 31 static uint32_t rotRight(uint32_t w, uint8_t n)
feb11 0:7a1237bd2d13 32 {
feb11 0:7a1237bd2d13 33 return rotLeft(w,32-n);
feb11 0:7a1237bd2d13 34 }
feb11 0:7a1237bd2d13 35
feb11 0:7a1237bd2d13 36 static uint32_t CH(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 37 {
feb11 0:7a1237bd2d13 38 return (x & y) ^ ((~x) & z);
feb11 0:7a1237bd2d13 39 }
feb11 0:7a1237bd2d13 40
feb11 0:7a1237bd2d13 41 static uint32_t MAJ(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 42 {
feb11 0:7a1237bd2d13 43 return (x & y) ^ (x & z) ^ (y & z);
feb11 0:7a1237bd2d13 44 }
feb11 0:7a1237bd2d13 45
feb11 0:7a1237bd2d13 46 static uint32_t BSIG0(uint32_t x)
feb11 0:7a1237bd2d13 47 {
feb11 0:7a1237bd2d13 48 return rotRight(x,2) ^ rotRight(x,13) ^ rotRight(x,22);
feb11 0:7a1237bd2d13 49 }
feb11 0:7a1237bd2d13 50
feb11 0:7a1237bd2d13 51 static uint32_t BSIG1(uint32_t x)
feb11 0:7a1237bd2d13 52 {
feb11 0:7a1237bd2d13 53 return rotRight(x,6) ^ rotRight(x,11) ^ rotRight(x,25);
feb11 0:7a1237bd2d13 54 }
feb11 0:7a1237bd2d13 55
feb11 0:7a1237bd2d13 56 static uint32_t SSIG0(uint32_t x)
feb11 0:7a1237bd2d13 57 {
feb11 0:7a1237bd2d13 58 return rotRight(x,7) ^ rotRight(x,18) ^ (x >> 3);
feb11 0:7a1237bd2d13 59 }
feb11 0:7a1237bd2d13 60
feb11 0:7a1237bd2d13 61 static uint32_t SSIG1(uint32_t x)
feb11 0:7a1237bd2d13 62 {
feb11 0:7a1237bd2d13 63 return rotRight(x,17) ^ rotRight(x,19) ^ (x >> 10);
feb11 0:7a1237bd2d13 64 }
feb11 0:7a1237bd2d13 65
feb11 0:7a1237bd2d13 66
feb11 0:7a1237bd2d13 67 static const uint32_t H[] =
feb11 0:7a1237bd2d13 68 {
feb11 0:7a1237bd2d13 69 // SHA-224
feb11 0:7a1237bd2d13 70 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
feb11 0:7a1237bd2d13 71 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
feb11 0:7a1237bd2d13 72
feb11 0:7a1237bd2d13 73 // SHA-256
feb11 0:7a1237bd2d13 74 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
feb11 0:7a1237bd2d13 75 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
feb11 0:7a1237bd2d13 76 };
feb11 0:7a1237bd2d13 77
feb11 0:7a1237bd2d13 78 SHA2_32::SHA2_32(SHA_32_TYPE t):
feb11 0:7a1237bd2d13 79 type(t),
feb11 0:7a1237bd2d13 80 totalBufferLength(0),
feb11 0:7a1237bd2d13 81 bufferLength(0)
feb11 0:7a1237bd2d13 82 {
feb11 0:7a1237bd2d13 83 switch(type)
feb11 0:7a1237bd2d13 84 {
feb11 0:7a1237bd2d13 85 case SHA_224:
feb11 0:7a1237bd2d13 86 h0 = H[0];
feb11 0:7a1237bd2d13 87 h1 = H[1];
feb11 0:7a1237bd2d13 88 h2 = H[2];
feb11 0:7a1237bd2d13 89 h3 = H[3];
feb11 0:7a1237bd2d13 90 h4 = H[4];
feb11 0:7a1237bd2d13 91 h5 = H[5];
feb11 0:7a1237bd2d13 92 h6 = H[6];
feb11 0:7a1237bd2d13 93 h7 = H[7];
feb11 0:7a1237bd2d13 94 break;
feb11 0:7a1237bd2d13 95
feb11 0:7a1237bd2d13 96 case SHA_256:
feb11 0:7a1237bd2d13 97 h0 = H[8];
feb11 0:7a1237bd2d13 98 h1 = H[9];
feb11 0:7a1237bd2d13 99 h2 = H[10];
feb11 0:7a1237bd2d13 100 h3 = H[11];
feb11 0:7a1237bd2d13 101 h4 = H[12];
feb11 0:7a1237bd2d13 102 h5 = H[13];
feb11 0:7a1237bd2d13 103 h6 = H[14];
feb11 0:7a1237bd2d13 104 h7 = H[15];
feb11 0:7a1237bd2d13 105 break;
feb11 0:7a1237bd2d13 106 }
feb11 0:7a1237bd2d13 107 }
feb11 0:7a1237bd2d13 108
feb11 0:7a1237bd2d13 109 void SHA2_32::add(uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 110 {
feb11 0:7a1237bd2d13 111 if(length < 64-bufferLength)
feb11 0:7a1237bd2d13 112 {
feb11 0:7a1237bd2d13 113 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 114 bufferLength += length;
feb11 0:7a1237bd2d13 115 totalBufferLength += length;
feb11 0:7a1237bd2d13 116 return;
feb11 0:7a1237bd2d13 117 }
feb11 0:7a1237bd2d13 118 int offset = 64-bufferLength;
feb11 0:7a1237bd2d13 119 memcpy(&buffer[bufferLength], in, offset);
feb11 0:7a1237bd2d13 120 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 121 while(length-offset > 64)
feb11 0:7a1237bd2d13 122 {
feb11 0:7a1237bd2d13 123 memcpy(buffer, &in[offset], 64);
feb11 0:7a1237bd2d13 124 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 125 offset += 64;
feb11 0:7a1237bd2d13 126 }
feb11 0:7a1237bd2d13 127 if(offset > length)
feb11 0:7a1237bd2d13 128 offset -= 64;
feb11 0:7a1237bd2d13 129 bufferLength = length - offset;
feb11 0:7a1237bd2d13 130 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 131 totalBufferLength += length;
feb11 0:7a1237bd2d13 132 }
feb11 0:7a1237bd2d13 133
feb11 0:7a1237bd2d13 134 void SHA2_32::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 135 {
feb11 0:7a1237bd2d13 136 uint16_t padding;
feb11 0:7a1237bd2d13 137 if(totalBufferLength % 64 < 56)
feb11 0:7a1237bd2d13 138 padding = 56 - (totalBufferLength % 64);
feb11 0:7a1237bd2d13 139 else
feb11 0:7a1237bd2d13 140 padding = 56 + (64 - (totalBufferLength % 64));
feb11 0:7a1237bd2d13 141 uint8_t val = 0x80;
feb11 0:7a1237bd2d13 142 add(&val, 1);
feb11 0:7a1237bd2d13 143 val = 0;
feb11 0:7a1237bd2d13 144 for(int i = 0; i < padding-1; ++i)
feb11 0:7a1237bd2d13 145 add(&val,1);
feb11 0:7a1237bd2d13 146 totalBufferLength -= padding;
feb11 0:7a1237bd2d13 147 uint64_t lengthBit = totalBufferLength * 8;
feb11 0:7a1237bd2d13 148 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 149 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 0:7a1237bd2d13 150 uint8_t tmp[4];
feb11 0:7a1237bd2d13 151 tmp[0] = lengthBitHigh >> 24;
feb11 0:7a1237bd2d13 152 tmp[1] = lengthBitHigh >> 16;
feb11 0:7a1237bd2d13 153 tmp[2] = lengthBitHigh >> 8;
feb11 0:7a1237bd2d13 154 tmp[3] = lengthBitHigh;
feb11 0:7a1237bd2d13 155 add(tmp, 4);
feb11 0:7a1237bd2d13 156 tmp[0] = lengthBitLow >> 24;
feb11 0:7a1237bd2d13 157 tmp[1] = lengthBitLow >> 16;
feb11 0:7a1237bd2d13 158 tmp[2] = lengthBitLow >> 8;
feb11 0:7a1237bd2d13 159 tmp[3] = lengthBitLow;
feb11 0:7a1237bd2d13 160 add(tmp, 4);
feb11 0:7a1237bd2d13 161
feb11 0:7a1237bd2d13 162 digest[0] = h0 >> 24;
feb11 0:7a1237bd2d13 163 digest[1] = h0 >> 16;
feb11 0:7a1237bd2d13 164 digest[2] = h0 >> 8;
feb11 0:7a1237bd2d13 165 digest[3] = h0;
feb11 0:7a1237bd2d13 166 digest[4] = h1 >> 24;
feb11 0:7a1237bd2d13 167 digest[5] = h1 >> 16;
feb11 0:7a1237bd2d13 168 digest[6] = h1 >> 8;
feb11 0:7a1237bd2d13 169 digest[7] = h1;
feb11 0:7a1237bd2d13 170 digest[8] = h2 >> 24;
feb11 0:7a1237bd2d13 171 digest[9] = h2 >> 16;
feb11 0:7a1237bd2d13 172 digest[10] = h2 >> 8;
feb11 0:7a1237bd2d13 173 digest[11] = h2;
feb11 0:7a1237bd2d13 174 digest[12] = h3 >> 24;
feb11 0:7a1237bd2d13 175 digest[13] = h3 >> 16;
feb11 0:7a1237bd2d13 176 digest[14] = h3 >> 8;
feb11 0:7a1237bd2d13 177 digest[15] = h3;
feb11 0:7a1237bd2d13 178 digest[16] = h4 >> 24;
feb11 0:7a1237bd2d13 179 digest[17] = h4 >> 16;
feb11 0:7a1237bd2d13 180 digest[18] = h4 >> 8;
feb11 0:7a1237bd2d13 181 digest[19] = h4;
feb11 0:7a1237bd2d13 182 digest[20] = h5 >> 24;
feb11 0:7a1237bd2d13 183 digest[21] = h5 >> 16;
feb11 0:7a1237bd2d13 184 digest[22] = h5 >> 8;
feb11 0:7a1237bd2d13 185 digest[23] = h5;
feb11 0:7a1237bd2d13 186 digest[24] = h6 >> 24;
feb11 0:7a1237bd2d13 187 digest[25] = h6 >> 16;
feb11 0:7a1237bd2d13 188 digest[26] = h6 >> 8;
feb11 0:7a1237bd2d13 189 digest[27] = h6;
feb11 0:7a1237bd2d13 190
feb11 0:7a1237bd2d13 191 if(type == SHA_256)
feb11 0:7a1237bd2d13 192 {
feb11 0:7a1237bd2d13 193 digest[28] = h7 >> 24;
feb11 0:7a1237bd2d13 194 digest[29] = h7 >> 16;
feb11 0:7a1237bd2d13 195 digest[30] = h7 >> 8;
feb11 0:7a1237bd2d13 196 digest[31] = h7;
feb11 0:7a1237bd2d13 197 }
feb11 0:7a1237bd2d13 198
feb11 0:7a1237bd2d13 199 // reset state
feb11 0:7a1237bd2d13 200 switch(type)
feb11 0:7a1237bd2d13 201 {
feb11 0:7a1237bd2d13 202 case SHA_224:
feb11 0:7a1237bd2d13 203 h0 = H[0];
feb11 0:7a1237bd2d13 204 h1 = H[1];
feb11 0:7a1237bd2d13 205 h2 = H[2];
feb11 0:7a1237bd2d13 206 h3 = H[3];
feb11 0:7a1237bd2d13 207 h4 = H[4];
feb11 0:7a1237bd2d13 208 h5 = H[5];
feb11 0:7a1237bd2d13 209 h6 = H[6];
feb11 0:7a1237bd2d13 210 h7 = H[7];
feb11 0:7a1237bd2d13 211 break;
feb11 0:7a1237bd2d13 212
feb11 0:7a1237bd2d13 213 case SHA_256:
feb11 0:7a1237bd2d13 214 h0 = H[8];
feb11 0:7a1237bd2d13 215 h1 = H[9];
feb11 0:7a1237bd2d13 216 h2 = H[10];
feb11 0:7a1237bd2d13 217 h3 = H[11];
feb11 0:7a1237bd2d13 218 h4 = H[12];
feb11 0:7a1237bd2d13 219 h5 = H[13];
feb11 0:7a1237bd2d13 220 h6 = H[14];
feb11 0:7a1237bd2d13 221 h7 = H[15];
feb11 0:7a1237bd2d13 222 break;
feb11 0:7a1237bd2d13 223 }
feb11 0:7a1237bd2d13 224 totalBufferLength = 0;
feb11 0:7a1237bd2d13 225 bufferLength = 0;
feb11 0:7a1237bd2d13 226 }
feb11 0:7a1237bd2d13 227
feb11 0:7a1237bd2d13 228 void SHA2_32::computeBlock(uint32_t *h02,
feb11 0:7a1237bd2d13 229 uint32_t *h12,
feb11 0:7a1237bd2d13 230 uint32_t *h22,
feb11 0:7a1237bd2d13 231 uint32_t *h32,
feb11 0:7a1237bd2d13 232 uint32_t *h42,
feb11 0:7a1237bd2d13 233 uint32_t *h52,
feb11 0:7a1237bd2d13 234 uint32_t *h62,
feb11 0:7a1237bd2d13 235 uint32_t *h72,
feb11 0:7a1237bd2d13 236 uint8_t *buffer)
feb11 0:7a1237bd2d13 237 {
feb11 0:7a1237bd2d13 238 uint32_t w[64];
feb11 0:7a1237bd2d13 239 for(int t = 0; t < 16; ++t)
feb11 0:7a1237bd2d13 240 w[t] = (buffer[t*4] << 24) | (buffer[t*4+1] << 16) | (buffer[t*4+2] << 8) | buffer[t*4+3];
feb11 0:7a1237bd2d13 241 for(int t = 16; t < 64; ++t)
feb11 0:7a1237bd2d13 242 w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16];
feb11 0:7a1237bd2d13 243
feb11 0:7a1237bd2d13 244 uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
feb11 0:7a1237bd2d13 245 for(int t = 0; t < 64; ++t)
feb11 0:7a1237bd2d13 246 {
feb11 0:7a1237bd2d13 247 uint32_t T1 = h + BSIG1(e) + CH(e,f,g) + K[t] + w[t];
feb11 0:7a1237bd2d13 248 uint32_t T2 = BSIG0(a) + MAJ(a,b,c);
feb11 0:7a1237bd2d13 249 h = g;
feb11 0:7a1237bd2d13 250 g = f;
feb11 0:7a1237bd2d13 251 f = e;
feb11 0:7a1237bd2d13 252 e = d + T1;
feb11 0:7a1237bd2d13 253 d = c;
feb11 0:7a1237bd2d13 254 c = b;
feb11 0:7a1237bd2d13 255 b = a;
feb11 0:7a1237bd2d13 256 a = T1 + T2;
feb11 0:7a1237bd2d13 257 }
feb11 0:7a1237bd2d13 258
feb11 0:7a1237bd2d13 259 *h02 += a;
feb11 0:7a1237bd2d13 260 *h12 += b;
feb11 0:7a1237bd2d13 261 *h22 += c;
feb11 0:7a1237bd2d13 262 *h32 += d;
feb11 0:7a1237bd2d13 263 *h42 += e;
feb11 0:7a1237bd2d13 264 *h52 += f;
feb11 0:7a1237bd2d13 265 *h62 += g;
feb11 0:7a1237bd2d13 266 *h72 += h;
feb11 0:7a1237bd2d13 267 }
feb11 0:7a1237bd2d13 268
feb11 0:7a1237bd2d13 269 void SHA2_32::computeDigest(SHA_32_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 270 {
feb11 0:7a1237bd2d13 271 uint32_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3];
feb11 0:7a1237bd2d13 272 uint32_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7];
feb11 0:7a1237bd2d13 273 int offset = 0;
feb11 0:7a1237bd2d13 274 while(length - offset >= 64)
feb11 0:7a1237bd2d13 275 {
feb11 0:7a1237bd2d13 276 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, &in[offset]);
feb11 0:7a1237bd2d13 277 offset += 64;
feb11 0:7a1237bd2d13 278 }
feb11 0:7a1237bd2d13 279 uint8_t bufferLength = length-offset;
feb11 0:7a1237bd2d13 280 uint8_t buffer[64];
feb11 0:7a1237bd2d13 281 memcpy(buffer, &in[offset],bufferLength);
feb11 0:7a1237bd2d13 282 uint16_t padding;
feb11 0:7a1237bd2d13 283 if(length % 64 < 56)
feb11 0:7a1237bd2d13 284 padding = 56 - (length % 64);
feb11 0:7a1237bd2d13 285 else
feb11 0:7a1237bd2d13 286 padding = 56 + (64 - (length % 64));
feb11 0:7a1237bd2d13 287 buffer[bufferLength] = 0x80;
feb11 0:7a1237bd2d13 288 bufferLength++;
feb11 0:7a1237bd2d13 289 padding--;
feb11 0:7a1237bd2d13 290 while(padding > 0)
feb11 0:7a1237bd2d13 291 {
feb11 0:7a1237bd2d13 292 if(bufferLength == 64)
feb11 0:7a1237bd2d13 293 {
feb11 0:7a1237bd2d13 294 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 295 bufferLength = 0;
feb11 0:7a1237bd2d13 296 }
feb11 0:7a1237bd2d13 297 buffer[bufferLength] = 0;
feb11 0:7a1237bd2d13 298 bufferLength++;
feb11 0:7a1237bd2d13 299 padding--;
feb11 0:7a1237bd2d13 300 }
feb11 0:7a1237bd2d13 301 uint64_t lengthBit = length * 8;
feb11 0:7a1237bd2d13 302 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 303 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 0:7a1237bd2d13 304 uint8_t tmp[4];
feb11 0:7a1237bd2d13 305 tmp[0] = lengthBitLow >> 24;
feb11 0:7a1237bd2d13 306 tmp[1] = lengthBitLow >> 16;
feb11 0:7a1237bd2d13 307 tmp[2] = lengthBitLow >> 8;
feb11 0:7a1237bd2d13 308 tmp[3] = lengthBitLow;
feb11 0:7a1237bd2d13 309 memcpy(&buffer[60], tmp, 4);
feb11 0:7a1237bd2d13 310 tmp[0] = lengthBitHigh >> 24;
feb11 0:7a1237bd2d13 311 tmp[1] = lengthBitHigh >> 16;
feb11 0:7a1237bd2d13 312 tmp[2] = lengthBitHigh >> 8;
feb11 0:7a1237bd2d13 313 tmp[3] = lengthBitHigh;
feb11 0:7a1237bd2d13 314 memcpy(&buffer[56], tmp, 4);
feb11 0:7a1237bd2d13 315 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 316
feb11 0:7a1237bd2d13 317 digest[0] = h0 >> 24;
feb11 0:7a1237bd2d13 318 digest[1] = h0 >> 16;
feb11 0:7a1237bd2d13 319 digest[2] = h0 >> 8;
feb11 0:7a1237bd2d13 320 digest[3] = h0;
feb11 0:7a1237bd2d13 321 digest[4] = h1 >> 24;
feb11 0:7a1237bd2d13 322 digest[5] = h1 >> 16;
feb11 0:7a1237bd2d13 323 digest[6] = h1 >> 8;
feb11 0:7a1237bd2d13 324 digest[7] = h1;
feb11 0:7a1237bd2d13 325 digest[8] = h2 >> 24;
feb11 0:7a1237bd2d13 326 digest[9] = h2 >> 16;
feb11 0:7a1237bd2d13 327 digest[10] = h2 >> 8;
feb11 0:7a1237bd2d13 328 digest[11] = h2;
feb11 0:7a1237bd2d13 329 digest[12] = h3 >> 24;
feb11 0:7a1237bd2d13 330 digest[13] = h3 >> 16;
feb11 0:7a1237bd2d13 331 digest[14] = h3 >> 8;
feb11 0:7a1237bd2d13 332 digest[15] = h3;
feb11 0:7a1237bd2d13 333 digest[16] = h4 >> 24;
feb11 0:7a1237bd2d13 334 digest[17] = h4 >> 16;
feb11 0:7a1237bd2d13 335 digest[18] = h4 >> 8;
feb11 0:7a1237bd2d13 336 digest[19] = h4;
feb11 0:7a1237bd2d13 337 digest[20] = h5 >> 24;
feb11 0:7a1237bd2d13 338 digest[21] = h5 >> 16;
feb11 0:7a1237bd2d13 339 digest[22] = h5 >> 8;
feb11 0:7a1237bd2d13 340 digest[23] = h5;
feb11 0:7a1237bd2d13 341 digest[24] = h6 >> 24;
feb11 0:7a1237bd2d13 342 digest[25] = h6 >> 16;
feb11 0:7a1237bd2d13 343 digest[26] = h6 >> 8;
feb11 0:7a1237bd2d13 344 digest[27] = h6;
feb11 0:7a1237bd2d13 345
feb11 0:7a1237bd2d13 346 if(type == SHA_256)
feb11 0:7a1237bd2d13 347 {
feb11 0:7a1237bd2d13 348 digest[28] = h7 >> 24;
feb11 0:7a1237bd2d13 349 digest[29] = h7 >> 16;
feb11 0:7a1237bd2d13 350 digest[30] = h7 >> 8;
feb11 0:7a1237bd2d13 351 digest[31] = h7;
feb11 0:7a1237bd2d13 352 }
feb11 0:7a1237bd2d13 353 }