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:
3:85c6ee25cf3e
initial import

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:7a1237bd2d13 1 #include "SHA2_64.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 0:7a1237bd2d13 3
feb11 0:7a1237bd2d13 4
feb11 0:7a1237bd2d13 5 static const uint64_t K[] =
feb11 0:7a1237bd2d13 6 {
feb11 0:7a1237bd2d13 7 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
feb11 0:7a1237bd2d13 8 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
feb11 0:7a1237bd2d13 9 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
feb11 0:7a1237bd2d13 10 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
feb11 0:7a1237bd2d13 11 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
feb11 0:7a1237bd2d13 12 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
feb11 0:7a1237bd2d13 13 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
feb11 0:7a1237bd2d13 14 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
feb11 0:7a1237bd2d13 15 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
feb11 0:7a1237bd2d13 16 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
feb11 0:7a1237bd2d13 17 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
feb11 0:7a1237bd2d13 18 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
feb11 0:7a1237bd2d13 19 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
feb11 0:7a1237bd2d13 20 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
feb11 0:7a1237bd2d13 21 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
feb11 0:7a1237bd2d13 22 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
feb11 0:7a1237bd2d13 23 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
feb11 0:7a1237bd2d13 24 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
feb11 0:7a1237bd2d13 25 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
feb11 0:7a1237bd2d13 26 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
feb11 0:7a1237bd2d13 27 };
feb11 0:7a1237bd2d13 28
feb11 0:7a1237bd2d13 29 static const uint64_t H[] =
feb11 0:7a1237bd2d13 30 {
feb11 0:7a1237bd2d13 31 // SHA-384
feb11 0:7a1237bd2d13 32 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
feb11 0:7a1237bd2d13 33 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
feb11 0:7a1237bd2d13 34
feb11 0:7a1237bd2d13 35 // SHA-512
feb11 0:7a1237bd2d13 36 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
feb11 0:7a1237bd2d13 37 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
feb11 0:7a1237bd2d13 38 };
feb11 0:7a1237bd2d13 39
feb11 0:7a1237bd2d13 40 static uint64_t revWord(uint64_t w)
feb11 0:7a1237bd2d13 41 {
feb11 0:7a1237bd2d13 42 uint8_t buffer[8];
feb11 0:7a1237bd2d13 43 buffer[0] = w >> 56;
feb11 0:7a1237bd2d13 44 buffer[1] = w >> 48;
feb11 0:7a1237bd2d13 45 buffer[2] = w >> 40;
feb11 0:7a1237bd2d13 46 buffer[3] = w >> 32;
feb11 0:7a1237bd2d13 47 buffer[4] = w >> 24;
feb11 0:7a1237bd2d13 48 buffer[5] = w >> 16;
feb11 0:7a1237bd2d13 49 buffer[6] = w >> 8;
feb11 0:7a1237bd2d13 50 buffer[7] = w;
feb11 0:7a1237bd2d13 51
feb11 0:7a1237bd2d13 52 uint64_t res = buffer[7];
feb11 0:7a1237bd2d13 53 res <<= 8;
feb11 0:7a1237bd2d13 54 res |= buffer[6];
feb11 0:7a1237bd2d13 55 res <<= 8;
feb11 0:7a1237bd2d13 56 res |= buffer[5];
feb11 0:7a1237bd2d13 57 res <<= 8;
feb11 0:7a1237bd2d13 58 res |= buffer[4];
feb11 0:7a1237bd2d13 59 res <<= 8;
feb11 0:7a1237bd2d13 60 res |= buffer[3];
feb11 0:7a1237bd2d13 61 res <<= 8;
feb11 0:7a1237bd2d13 62 res |= buffer[2];
feb11 0:7a1237bd2d13 63 res <<= 8;
feb11 0:7a1237bd2d13 64 res |= buffer[1];
feb11 0:7a1237bd2d13 65 res <<= 8;
feb11 0:7a1237bd2d13 66 res |= buffer[0];
feb11 0:7a1237bd2d13 67
feb11 0:7a1237bd2d13 68 return res;
feb11 0:7a1237bd2d13 69 }
feb11 0:7a1237bd2d13 70
feb11 0:7a1237bd2d13 71 static uint64_t rotLeft(uint64_t w, uint8_t n)
feb11 0:7a1237bd2d13 72 {
feb11 0:7a1237bd2d13 73 return (w << n) | (w >> (64-n));
feb11 0:7a1237bd2d13 74 }
feb11 0:7a1237bd2d13 75
feb11 0:7a1237bd2d13 76 static uint64_t rotRight(uint64_t w, uint8_t n)
feb11 0:7a1237bd2d13 77 {
feb11 0:7a1237bd2d13 78 return rotLeft(w,64-n);
feb11 0:7a1237bd2d13 79 }
feb11 0:7a1237bd2d13 80
feb11 0:7a1237bd2d13 81 static uint64_t CH(uint64_t x, uint64_t y, uint64_t z)
feb11 0:7a1237bd2d13 82 {
feb11 0:7a1237bd2d13 83 return (x & y) ^ ((~x) & z);
feb11 0:7a1237bd2d13 84 }
feb11 0:7a1237bd2d13 85
feb11 0:7a1237bd2d13 86 static uint64_t MAJ(uint64_t x, uint64_t y, uint64_t z)
feb11 0:7a1237bd2d13 87 {
feb11 0:7a1237bd2d13 88 return (x & y) ^ (x & z) ^ (y & z);
feb11 0:7a1237bd2d13 89 }
feb11 0:7a1237bd2d13 90
feb11 0:7a1237bd2d13 91 static uint64_t BSIG0(uint64_t x)
feb11 0:7a1237bd2d13 92 {
feb11 0:7a1237bd2d13 93 return rotRight(x,28) ^ rotRight(x,34) ^ rotRight(x,39);
feb11 0:7a1237bd2d13 94 }
feb11 0:7a1237bd2d13 95
feb11 0:7a1237bd2d13 96 static uint64_t BSIG1(uint64_t x)
feb11 0:7a1237bd2d13 97 {
feb11 0:7a1237bd2d13 98 return rotRight(x,14) ^ rotRight(x,18) ^ rotRight(x,41);
feb11 0:7a1237bd2d13 99 }
feb11 0:7a1237bd2d13 100
feb11 0:7a1237bd2d13 101 static uint64_t SSIG0(uint64_t x)
feb11 0:7a1237bd2d13 102 {
feb11 0:7a1237bd2d13 103 return rotRight(x,1) ^ rotRight(x,8) ^ (x >> 7);
feb11 0:7a1237bd2d13 104 }
feb11 0:7a1237bd2d13 105
feb11 0:7a1237bd2d13 106 static uint64_t SSIG1(uint64_t x)
feb11 0:7a1237bd2d13 107 {
feb11 0:7a1237bd2d13 108 return rotRight(x,19) ^ rotRight(x,61) ^ (x>>6);
feb11 0:7a1237bd2d13 109 }
feb11 0:7a1237bd2d13 110
feb11 0:7a1237bd2d13 111 SHA2_64::SHA2_64(SHA2_64_TYPE t):
feb11 0:7a1237bd2d13 112 type(t),
feb11 0:7a1237bd2d13 113 totalBufferLength(0),
feb11 0:7a1237bd2d13 114 bufferLength(0)
feb11 0:7a1237bd2d13 115 {
feb11 0:7a1237bd2d13 116 switch(type)
feb11 0:7a1237bd2d13 117 {
feb11 0:7a1237bd2d13 118 case SHA_384:
feb11 0:7a1237bd2d13 119 h0 = H[0];
feb11 0:7a1237bd2d13 120 h1 = H[1];
feb11 0:7a1237bd2d13 121 h2 = H[2];
feb11 0:7a1237bd2d13 122 h3 = H[3];
feb11 0:7a1237bd2d13 123 h4 = H[4];
feb11 0:7a1237bd2d13 124 h5 = H[5];
feb11 0:7a1237bd2d13 125 h6 = H[6];
feb11 0:7a1237bd2d13 126 h7 = H[7];
feb11 0:7a1237bd2d13 127 break;
feb11 0:7a1237bd2d13 128
feb11 0:7a1237bd2d13 129 case SHA_512:
feb11 0:7a1237bd2d13 130 h0 = H[8];
feb11 0:7a1237bd2d13 131 h1 = H[9];
feb11 0:7a1237bd2d13 132 h2 = H[10];
feb11 0:7a1237bd2d13 133 h3 = H[11];
feb11 0:7a1237bd2d13 134 h4 = H[12];
feb11 0:7a1237bd2d13 135 h5 = H[13];
feb11 0:7a1237bd2d13 136 h6 = H[14];
feb11 0:7a1237bd2d13 137 h7 = H[15];
feb11 0:7a1237bd2d13 138 break;
feb11 0:7a1237bd2d13 139 }
feb11 0:7a1237bd2d13 140 }
feb11 0:7a1237bd2d13 141
feb11 0:7a1237bd2d13 142 void SHA2_64::add(uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 143 {
feb11 0:7a1237bd2d13 144 if(length < 128-bufferLength)
feb11 0:7a1237bd2d13 145 {
feb11 0:7a1237bd2d13 146 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 147 bufferLength += length;
feb11 0:7a1237bd2d13 148 totalBufferLength += length;
feb11 0:7a1237bd2d13 149 return;
feb11 0:7a1237bd2d13 150 }
feb11 0:7a1237bd2d13 151 int offset = 128-bufferLength;
feb11 0:7a1237bd2d13 152 memcpy(&buffer[bufferLength], in, offset);
feb11 0:7a1237bd2d13 153 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 154 while(length-offset > 128)
feb11 0:7a1237bd2d13 155 {
feb11 0:7a1237bd2d13 156 memcpy(buffer, &in[offset], 128);
feb11 0:7a1237bd2d13 157 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 158 offset += 128;
feb11 0:7a1237bd2d13 159 }
feb11 0:7a1237bd2d13 160 if(offset > length)
feb11 0:7a1237bd2d13 161 offset -= 128;
feb11 0:7a1237bd2d13 162 bufferLength = length - offset;
feb11 0:7a1237bd2d13 163 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 164 totalBufferLength += length;
feb11 0:7a1237bd2d13 165 }
feb11 0:7a1237bd2d13 166
feb11 0:7a1237bd2d13 167 void SHA2_64::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 168 {
feb11 0:7a1237bd2d13 169 uint16_t padding;
feb11 0:7a1237bd2d13 170 if(totalBufferLength % 128 < 112)
feb11 0:7a1237bd2d13 171 padding = 112 - (totalBufferLength % 128);
feb11 0:7a1237bd2d13 172 else
feb11 0:7a1237bd2d13 173 padding = 112 + (128 - (totalBufferLength % 128));
feb11 0:7a1237bd2d13 174 uint8_t val = 0x80;
feb11 0:7a1237bd2d13 175 add(&val, 1);
feb11 0:7a1237bd2d13 176 val = 0;
feb11 0:7a1237bd2d13 177 for(int i = 0; i < padding-1; ++i)
feb11 0:7a1237bd2d13 178 add(&val,1);
feb11 0:7a1237bd2d13 179 totalBufferLength -= padding;
feb11 0:7a1237bd2d13 180 uint64_t lengthBit = 0;
feb11 0:7a1237bd2d13 181 add((uint8_t*)&lengthBit, 8);
feb11 0:7a1237bd2d13 182 lengthBit = (totalBufferLength - 8) * 8;
feb11 0:7a1237bd2d13 183 lengthBit = revWord(lengthBit);
feb11 0:7a1237bd2d13 184 add((uint8_t*)&lengthBit, 8);
feb11 0:7a1237bd2d13 185
feb11 0:7a1237bd2d13 186 h0 = revWord(h0);
feb11 0:7a1237bd2d13 187 h1 = revWord(h1);
feb11 0:7a1237bd2d13 188 h2 = revWord(h2);
feb11 0:7a1237bd2d13 189 h3 = revWord(h3);
feb11 0:7a1237bd2d13 190 h4 = revWord(h4);
feb11 0:7a1237bd2d13 191 h5 = revWord(h5);
feb11 0:7a1237bd2d13 192
feb11 0:7a1237bd2d13 193
feb11 0:7a1237bd2d13 194 memcpy(digest, &h0, 8);
feb11 0:7a1237bd2d13 195 memcpy(&digest[8], &h1, 8);
feb11 0:7a1237bd2d13 196 memcpy(&digest[16], &h2, 8);
feb11 0:7a1237bd2d13 197 memcpy(&digest[24], &h3, 8);
feb11 0:7a1237bd2d13 198 memcpy(&digest[32], &h4, 8);
feb11 0:7a1237bd2d13 199 memcpy(&digest[40], &h5, 8);
feb11 0:7a1237bd2d13 200
feb11 0:7a1237bd2d13 201 if(type == SHA_512)
feb11 0:7a1237bd2d13 202 {
feb11 0:7a1237bd2d13 203 h6 = revWord(h6);
feb11 0:7a1237bd2d13 204 h7 = revWord(h7);
feb11 0:7a1237bd2d13 205 memcpy(&digest[48], &h6, 8);
feb11 0:7a1237bd2d13 206 memcpy(&digest[56], &h7, 8);
feb11 0:7a1237bd2d13 207 }
feb11 0:7a1237bd2d13 208
feb11 0:7a1237bd2d13 209 // reset state
feb11 0:7a1237bd2d13 210 switch(type)
feb11 0:7a1237bd2d13 211 {
feb11 0:7a1237bd2d13 212 case SHA_384:
feb11 0:7a1237bd2d13 213 h0 = H[0];
feb11 0:7a1237bd2d13 214 h1 = H[1];
feb11 0:7a1237bd2d13 215 h2 = H[2];
feb11 0:7a1237bd2d13 216 h3 = H[3];
feb11 0:7a1237bd2d13 217 h4 = H[4];
feb11 0:7a1237bd2d13 218 h5 = H[5];
feb11 0:7a1237bd2d13 219 h6 = H[6];
feb11 0:7a1237bd2d13 220 h7 = H[7];
feb11 0:7a1237bd2d13 221 break;
feb11 0:7a1237bd2d13 222
feb11 0:7a1237bd2d13 223 case SHA_512:
feb11 0:7a1237bd2d13 224 h0 = H[8];
feb11 0:7a1237bd2d13 225 h1 = H[9];
feb11 0:7a1237bd2d13 226 h2 = H[10];
feb11 0:7a1237bd2d13 227 h3 = H[11];
feb11 0:7a1237bd2d13 228 h4 = H[12];
feb11 0:7a1237bd2d13 229 h5 = H[13];
feb11 0:7a1237bd2d13 230 h6 = H[14];
feb11 0:7a1237bd2d13 231 h7 = H[15];
feb11 0:7a1237bd2d13 232 break;
feb11 0:7a1237bd2d13 233 }
feb11 0:7a1237bd2d13 234 totalBufferLength = 0;
feb11 0:7a1237bd2d13 235 bufferLength = 0;
feb11 0:7a1237bd2d13 236 }
feb11 0:7a1237bd2d13 237
feb11 0:7a1237bd2d13 238 void SHA2_64::computeBlock(uint64_t *h02,
feb11 0:7a1237bd2d13 239 uint64_t *h12,
feb11 0:7a1237bd2d13 240 uint64_t *h22,
feb11 0:7a1237bd2d13 241 uint64_t *h32,
feb11 0:7a1237bd2d13 242 uint64_t *h42,
feb11 0:7a1237bd2d13 243 uint64_t *h52,
feb11 0:7a1237bd2d13 244 uint64_t *h62,
feb11 0:7a1237bd2d13 245 uint64_t *h72,
feb11 0:7a1237bd2d13 246 uint8_t *buffer)
feb11 0:7a1237bd2d13 247 {
feb11 0:7a1237bd2d13 248 uint64_t w[80];
feb11 0:7a1237bd2d13 249 for(int t = 0; t < 16; ++t)
feb11 0:7a1237bd2d13 250 {
feb11 0:7a1237bd2d13 251 memcpy(&w[t], &buffer[t*8], 8);
feb11 0:7a1237bd2d13 252 w[t] = revWord(w[t]);
feb11 0:7a1237bd2d13 253 }
feb11 0:7a1237bd2d13 254 for(int t = 16; t < 80; ++t)
feb11 0:7a1237bd2d13 255 w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16];
feb11 0:7a1237bd2d13 256
feb11 0:7a1237bd2d13 257 uint64_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
feb11 0:7a1237bd2d13 258 for(int t = 0; t < 80; ++t)
feb11 0:7a1237bd2d13 259 {
feb11 0:7a1237bd2d13 260 uint64_t T1 = h + BSIG1(e) + CH(e,f,g) + K[t] + w[t];
feb11 0:7a1237bd2d13 261 uint64_t T2 = BSIG0(a) + MAJ(a,b,c);
feb11 0:7a1237bd2d13 262 h = g;
feb11 0:7a1237bd2d13 263 g = f;
feb11 0:7a1237bd2d13 264 f = e;
feb11 0:7a1237bd2d13 265 e = d + T1;
feb11 0:7a1237bd2d13 266 d = c;
feb11 0:7a1237bd2d13 267 c = b;
feb11 0:7a1237bd2d13 268 b = a;
feb11 0:7a1237bd2d13 269 a = T1 + T2;
feb11 0:7a1237bd2d13 270 }
feb11 0:7a1237bd2d13 271 *h02 += a;
feb11 0:7a1237bd2d13 272 *h12 += b;
feb11 0:7a1237bd2d13 273 *h22 += c;
feb11 0:7a1237bd2d13 274 *h32 += d;
feb11 0:7a1237bd2d13 275 *h42 += e;
feb11 0:7a1237bd2d13 276 *h52 += f;
feb11 0:7a1237bd2d13 277 *h62 += g;
feb11 0:7a1237bd2d13 278 *h72 += h;
feb11 0:7a1237bd2d13 279 }
feb11 0:7a1237bd2d13 280
feb11 0:7a1237bd2d13 281 void SHA2_64::computeDigest(SHA2_64_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 282 {
feb11 0:7a1237bd2d13 283 uint64_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3];
feb11 0:7a1237bd2d13 284 uint64_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7];
feb11 0:7a1237bd2d13 285 int offset = 0;
feb11 0:7a1237bd2d13 286 while(length - offset >= 128)
feb11 0:7a1237bd2d13 287 {
feb11 0:7a1237bd2d13 288 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, &in[offset]);
feb11 0:7a1237bd2d13 289 offset += 128;
feb11 0:7a1237bd2d13 290 }
feb11 0:7a1237bd2d13 291 uint8_t bufferLength = length-offset;
feb11 0:7a1237bd2d13 292 uint8_t buffer[128];
feb11 0:7a1237bd2d13 293 memcpy(buffer, &in[offset],bufferLength);
feb11 0:7a1237bd2d13 294 uint16_t padding;
feb11 0:7a1237bd2d13 295 if(length % 128 < 112)
feb11 0:7a1237bd2d13 296 padding = 112 - (length % 128);
feb11 0:7a1237bd2d13 297 else
feb11 0:7a1237bd2d13 298 padding = 112 + (128 - (length % 128));
feb11 0:7a1237bd2d13 299 buffer[bufferLength] = 0x80;
feb11 0:7a1237bd2d13 300 bufferLength++;
feb11 0:7a1237bd2d13 301 padding--;
feb11 0:7a1237bd2d13 302 while(padding > 0)
feb11 0:7a1237bd2d13 303 {
feb11 0:7a1237bd2d13 304 if(bufferLength == 128)
feb11 0:7a1237bd2d13 305 {
feb11 0:7a1237bd2d13 306 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 307 bufferLength = 0;
feb11 0:7a1237bd2d13 308 }
feb11 0:7a1237bd2d13 309 buffer[bufferLength] = 0;
feb11 0:7a1237bd2d13 310 bufferLength++;
feb11 0:7a1237bd2d13 311 padding--;
feb11 0:7a1237bd2d13 312 }
feb11 0:7a1237bd2d13 313 uint64_t lengthBit = length * 8;
feb11 0:7a1237bd2d13 314 lengthBit = revWord(lengthBit);
feb11 0:7a1237bd2d13 315 memset(&buffer[112], 0, 8);
feb11 0:7a1237bd2d13 316 memcpy(&buffer[120], &lengthBit, 8);
feb11 0:7a1237bd2d13 317 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 318
feb11 0:7a1237bd2d13 319 h0 = revWord(h0);
feb11 0:7a1237bd2d13 320 h1 = revWord(h1);
feb11 0:7a1237bd2d13 321 h2 = revWord(h2);
feb11 0:7a1237bd2d13 322 h3 = revWord(h3);
feb11 0:7a1237bd2d13 323 h4 = revWord(h4);
feb11 0:7a1237bd2d13 324 h5 = revWord(h5);
feb11 0:7a1237bd2d13 325
feb11 0:7a1237bd2d13 326
feb11 0:7a1237bd2d13 327 memcpy(digest, &h0, 8);
feb11 0:7a1237bd2d13 328 memcpy(&digest[8], &h1, 8);
feb11 0:7a1237bd2d13 329 memcpy(&digest[16], &h2, 8);
feb11 0:7a1237bd2d13 330 memcpy(&digest[24], &h3, 8);
feb11 0:7a1237bd2d13 331 memcpy(&digest[32], &h4, 8);
feb11 0:7a1237bd2d13 332 memcpy(&digest[40], &h5, 8);
feb11 0:7a1237bd2d13 333
feb11 0:7a1237bd2d13 334 if(type == SHA_512)
feb11 0:7a1237bd2d13 335 {
feb11 0:7a1237bd2d13 336 h6 = revWord(h6);
feb11 0:7a1237bd2d13 337 h7 = revWord(h7);
feb11 0:7a1237bd2d13 338 memcpy(&digest[48], &h6, 8);
feb11 0:7a1237bd2d13 339 memcpy(&digest[56], &h7, 8);
feb11 0:7a1237bd2d13 340 }
feb11 0:7a1237bd2d13 341 }
feb11 0:7a1237bd2d13 342