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:
Thu Sep 12 15:08:51 2013 +0000
Revision:
5:06cd9c8afa0b
Parent:
4:0da19393bd57
Child:
6:19aa835f2bbb
change API & small improvements in SHA-2

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