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:
Wed Sep 11 17:22:40 2013 +0000
Revision:
3:85c6ee25cf3e
Parent:
0:7a1237bd2d13
Child:
4:0da19393bd57
improved speed of MD2, MD5, SHA-1 and SHA-2 (32bits)

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 3:85c6ee25cf3e 42 return (w >> 56)
feb11 3:85c6ee25cf3e 43 | ((w & 0x00FF000000000000) >> 40)
feb11 3:85c6ee25cf3e 44 | ((w & 0x0000FF0000000000) >> 24)
feb11 3:85c6ee25cf3e 45 | ((w & 0x000000FF00000000) >> 8)
feb11 3:85c6ee25cf3e 46 | ((w & 0x00000000FF000000) << 8)
feb11 3:85c6ee25cf3e 47 | ((w & 0x0000000000FF0000) << 24)
feb11 3:85c6ee25cf3e 48 | ((w & 0x000000000000FF00) << 40)
feb11 3:85c6ee25cf3e 49 | ((w & 0x00000000000000FF) << 56);
feb11 0:7a1237bd2d13 50 }
feb11 0:7a1237bd2d13 51
feb11 3:85c6ee25cf3e 52 #define ROTL(W,N) (((W) << (N)) | ((W) >> (64-(N))))
feb11 3:85c6ee25cf3e 53 #define ROTR(W,N) (((W) >> (N)) | ((W) << (64-(N))))
feb11 3:85c6ee25cf3e 54 #define CH(X,Y,Z) (((X) & (Y)) ^ ((~(X)) & (Z)))
feb11 3:85c6ee25cf3e 55 #define MAJ(X,Y,Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z)))
feb11 3:85c6ee25cf3e 56 #define BSIG0(X) (ROTR(X,28) ^ ROTR(X,34) ^ ROTR(X,39))
feb11 3:85c6ee25cf3e 57 #define BSIG1(X) (ROTR(X,14) ^ ROTR(X,18) ^ ROTR(X,41))
feb11 3:85c6ee25cf3e 58 #define SSIG0(X) (ROTR((X),1) ^ ROTR((X),8) ^ ((X) >> 7))
feb11 3:85c6ee25cf3e 59 #define SSIG1(X) (ROTR((X),19) ^ ROTR((X),61) ^ ((X) >> 6))
feb11 0:7a1237bd2d13 60
feb11 3:85c6ee25cf3e 61
feb11 0:7a1237bd2d13 62
feb11 0:7a1237bd2d13 63 SHA2_64::SHA2_64(SHA2_64_TYPE t):
feb11 0:7a1237bd2d13 64 type(t),
feb11 0:7a1237bd2d13 65 totalBufferLength(0),
feb11 0:7a1237bd2d13 66 bufferLength(0)
feb11 0:7a1237bd2d13 67 {
feb11 0:7a1237bd2d13 68 switch(type)
feb11 0:7a1237bd2d13 69 {
feb11 0:7a1237bd2d13 70 case SHA_384:
feb11 0:7a1237bd2d13 71 h0 = H[0];
feb11 0:7a1237bd2d13 72 h1 = H[1];
feb11 0:7a1237bd2d13 73 h2 = H[2];
feb11 0:7a1237bd2d13 74 h3 = H[3];
feb11 0:7a1237bd2d13 75 h4 = H[4];
feb11 0:7a1237bd2d13 76 h5 = H[5];
feb11 0:7a1237bd2d13 77 h6 = H[6];
feb11 0:7a1237bd2d13 78 h7 = H[7];
feb11 0:7a1237bd2d13 79 break;
feb11 0:7a1237bd2d13 80
feb11 0:7a1237bd2d13 81 case SHA_512:
feb11 0:7a1237bd2d13 82 h0 = H[8];
feb11 0:7a1237bd2d13 83 h1 = H[9];
feb11 0:7a1237bd2d13 84 h2 = H[10];
feb11 0:7a1237bd2d13 85 h3 = H[11];
feb11 0:7a1237bd2d13 86 h4 = H[12];
feb11 0:7a1237bd2d13 87 h5 = H[13];
feb11 0:7a1237bd2d13 88 h6 = H[14];
feb11 0:7a1237bd2d13 89 h7 = H[15];
feb11 0:7a1237bd2d13 90 break;
feb11 0:7a1237bd2d13 91 }
feb11 0:7a1237bd2d13 92 }
feb11 0:7a1237bd2d13 93
feb11 0:7a1237bd2d13 94 void SHA2_64::add(uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 95 {
feb11 0:7a1237bd2d13 96 if(length < 128-bufferLength)
feb11 0:7a1237bd2d13 97 {
feb11 0:7a1237bd2d13 98 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 99 bufferLength += length;
feb11 0:7a1237bd2d13 100 totalBufferLength += length;
feb11 0:7a1237bd2d13 101 return;
feb11 0:7a1237bd2d13 102 }
feb11 0:7a1237bd2d13 103 int offset = 128-bufferLength;
feb11 0:7a1237bd2d13 104 memcpy(&buffer[bufferLength], in, offset);
feb11 0:7a1237bd2d13 105 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 106 while(length-offset > 128)
feb11 0:7a1237bd2d13 107 {
feb11 0:7a1237bd2d13 108 memcpy(buffer, &in[offset], 128);
feb11 0:7a1237bd2d13 109 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 110 offset += 128;
feb11 0:7a1237bd2d13 111 }
feb11 0:7a1237bd2d13 112 if(offset > length)
feb11 0:7a1237bd2d13 113 offset -= 128;
feb11 0:7a1237bd2d13 114 bufferLength = length - offset;
feb11 0:7a1237bd2d13 115 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 116 totalBufferLength += length;
feb11 0:7a1237bd2d13 117 }
feb11 0:7a1237bd2d13 118
feb11 0:7a1237bd2d13 119 void SHA2_64::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 120 {
feb11 0:7a1237bd2d13 121 uint16_t padding;
feb11 0:7a1237bd2d13 122 if(totalBufferLength % 128 < 112)
feb11 0:7a1237bd2d13 123 padding = 112 - (totalBufferLength % 128);
feb11 0:7a1237bd2d13 124 else
feb11 0:7a1237bd2d13 125 padding = 112 + (128 - (totalBufferLength % 128));
feb11 0:7a1237bd2d13 126 uint8_t val = 0x80;
feb11 0:7a1237bd2d13 127 add(&val, 1);
feb11 0:7a1237bd2d13 128 val = 0;
feb11 0:7a1237bd2d13 129 for(int i = 0; i < padding-1; ++i)
feb11 0:7a1237bd2d13 130 add(&val,1);
feb11 0:7a1237bd2d13 131 totalBufferLength -= padding;
feb11 0:7a1237bd2d13 132 uint64_t lengthBit = 0;
feb11 0:7a1237bd2d13 133 add((uint8_t*)&lengthBit, 8);
feb11 0:7a1237bd2d13 134 lengthBit = (totalBufferLength - 8) * 8;
feb11 0:7a1237bd2d13 135 lengthBit = revWord(lengthBit);
feb11 0:7a1237bd2d13 136 add((uint8_t*)&lengthBit, 8);
feb11 0:7a1237bd2d13 137
feb11 0:7a1237bd2d13 138 h0 = revWord(h0);
feb11 0:7a1237bd2d13 139 h1 = revWord(h1);
feb11 0:7a1237bd2d13 140 h2 = revWord(h2);
feb11 0:7a1237bd2d13 141 h3 = revWord(h3);
feb11 0:7a1237bd2d13 142 h4 = revWord(h4);
feb11 0:7a1237bd2d13 143 h5 = revWord(h5);
feb11 0:7a1237bd2d13 144
feb11 0:7a1237bd2d13 145
feb11 0:7a1237bd2d13 146 memcpy(digest, &h0, 8);
feb11 0:7a1237bd2d13 147 memcpy(&digest[8], &h1, 8);
feb11 0:7a1237bd2d13 148 memcpy(&digest[16], &h2, 8);
feb11 0:7a1237bd2d13 149 memcpy(&digest[24], &h3, 8);
feb11 0:7a1237bd2d13 150 memcpy(&digest[32], &h4, 8);
feb11 0:7a1237bd2d13 151 memcpy(&digest[40], &h5, 8);
feb11 0:7a1237bd2d13 152
feb11 0:7a1237bd2d13 153 if(type == SHA_512)
feb11 0:7a1237bd2d13 154 {
feb11 0:7a1237bd2d13 155 h6 = revWord(h6);
feb11 0:7a1237bd2d13 156 h7 = revWord(h7);
feb11 0:7a1237bd2d13 157 memcpy(&digest[48], &h6, 8);
feb11 0:7a1237bd2d13 158 memcpy(&digest[56], &h7, 8);
feb11 0:7a1237bd2d13 159 }
feb11 0:7a1237bd2d13 160
feb11 0:7a1237bd2d13 161 // reset state
feb11 0:7a1237bd2d13 162 switch(type)
feb11 0:7a1237bd2d13 163 {
feb11 0:7a1237bd2d13 164 case SHA_384:
feb11 0:7a1237bd2d13 165 h0 = H[0];
feb11 0:7a1237bd2d13 166 h1 = H[1];
feb11 0:7a1237bd2d13 167 h2 = H[2];
feb11 0:7a1237bd2d13 168 h3 = H[3];
feb11 0:7a1237bd2d13 169 h4 = H[4];
feb11 0:7a1237bd2d13 170 h5 = H[5];
feb11 0:7a1237bd2d13 171 h6 = H[6];
feb11 0:7a1237bd2d13 172 h7 = H[7];
feb11 0:7a1237bd2d13 173 break;
feb11 0:7a1237bd2d13 174
feb11 0:7a1237bd2d13 175 case SHA_512:
feb11 0:7a1237bd2d13 176 h0 = H[8];
feb11 0:7a1237bd2d13 177 h1 = H[9];
feb11 0:7a1237bd2d13 178 h2 = H[10];
feb11 0:7a1237bd2d13 179 h3 = H[11];
feb11 0:7a1237bd2d13 180 h4 = H[12];
feb11 0:7a1237bd2d13 181 h5 = H[13];
feb11 0:7a1237bd2d13 182 h6 = H[14];
feb11 0:7a1237bd2d13 183 h7 = H[15];
feb11 0:7a1237bd2d13 184 break;
feb11 0:7a1237bd2d13 185 }
feb11 0:7a1237bd2d13 186 totalBufferLength = 0;
feb11 0:7a1237bd2d13 187 bufferLength = 0;
feb11 0:7a1237bd2d13 188 }
feb11 0:7a1237bd2d13 189
feb11 0:7a1237bd2d13 190 void SHA2_64::computeBlock(uint64_t *h02,
feb11 0:7a1237bd2d13 191 uint64_t *h12,
feb11 0:7a1237bd2d13 192 uint64_t *h22,
feb11 0:7a1237bd2d13 193 uint64_t *h32,
feb11 0:7a1237bd2d13 194 uint64_t *h42,
feb11 0:7a1237bd2d13 195 uint64_t *h52,
feb11 0:7a1237bd2d13 196 uint64_t *h62,
feb11 0:7a1237bd2d13 197 uint64_t *h72,
feb11 0:7a1237bd2d13 198 uint8_t *buffer)
feb11 0:7a1237bd2d13 199 {
feb11 0:7a1237bd2d13 200 uint64_t w[80];
feb11 0:7a1237bd2d13 201 for(int t = 0; t < 16; ++t)
feb11 0:7a1237bd2d13 202 {
feb11 0:7a1237bd2d13 203 memcpy(&w[t], &buffer[t*8], 8);
feb11 0:7a1237bd2d13 204 w[t] = revWord(w[t]);
feb11 0:7a1237bd2d13 205 }
feb11 0:7a1237bd2d13 206 for(int t = 16; t < 80; ++t)
feb11 0:7a1237bd2d13 207 w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16];
feb11 0:7a1237bd2d13 208
feb11 0:7a1237bd2d13 209 uint64_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
feb11 0:7a1237bd2d13 210 for(int t = 0; t < 80; ++t)
feb11 0:7a1237bd2d13 211 {
feb11 0:7a1237bd2d13 212 uint64_t T1 = h + BSIG1(e) + CH(e,f,g) + K[t] + w[t];
feb11 0:7a1237bd2d13 213 uint64_t T2 = BSIG0(a) + MAJ(a,b,c);
feb11 0:7a1237bd2d13 214 h = g;
feb11 0:7a1237bd2d13 215 g = f;
feb11 0:7a1237bd2d13 216 f = e;
feb11 0:7a1237bd2d13 217 e = d + T1;
feb11 0:7a1237bd2d13 218 d = c;
feb11 0:7a1237bd2d13 219 c = b;
feb11 0:7a1237bd2d13 220 b = a;
feb11 0:7a1237bd2d13 221 a = T1 + T2;
feb11 0:7a1237bd2d13 222 }
feb11 0:7a1237bd2d13 223 *h02 += a;
feb11 0:7a1237bd2d13 224 *h12 += b;
feb11 0:7a1237bd2d13 225 *h22 += c;
feb11 0:7a1237bd2d13 226 *h32 += d;
feb11 0:7a1237bd2d13 227 *h42 += e;
feb11 0:7a1237bd2d13 228 *h52 += f;
feb11 0:7a1237bd2d13 229 *h62 += g;
feb11 0:7a1237bd2d13 230 *h72 += h;
feb11 0:7a1237bd2d13 231 }
feb11 0:7a1237bd2d13 232
feb11 0:7a1237bd2d13 233 void SHA2_64::computeDigest(SHA2_64_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 234 {
feb11 3:85c6ee25cf3e 235 uint64_t lengthBit = length * 8;
feb11 0:7a1237bd2d13 236 uint64_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3];
feb11 0:7a1237bd2d13 237 uint64_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7];
feb11 3:85c6ee25cf3e 238
feb11 3:85c6ee25cf3e 239 int padding;
feb11 0:7a1237bd2d13 240 if(length % 128 < 112)
feb11 0:7a1237bd2d13 241 padding = 112 - (length % 128);
feb11 0:7a1237bd2d13 242 else
feb11 0:7a1237bd2d13 243 padding = 112 + (128 - (length % 128));
feb11 3:85c6ee25cf3e 244
feb11 3:85c6ee25cf3e 245 while(length >= 128)
feb11 0:7a1237bd2d13 246 {
feb11 3:85c6ee25cf3e 247 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, in);
feb11 3:85c6ee25cf3e 248 in += 128;
feb11 3:85c6ee25cf3e 249 length -= 128;
feb11 0:7a1237bd2d13 250 }
feb11 3:85c6ee25cf3e 251 uint8_t buffer[128];
feb11 3:85c6ee25cf3e 252 memcpy(buffer, in,length);
feb11 3:85c6ee25cf3e 253 buffer[length] = 0x80;
feb11 3:85c6ee25cf3e 254 length++;
feb11 3:85c6ee25cf3e 255 padding--;
feb11 3:85c6ee25cf3e 256
feb11 3:85c6ee25cf3e 257 if(padding+length == 112)
feb11 3:85c6ee25cf3e 258 memset(&buffer[length], 0, padding);
feb11 3:85c6ee25cf3e 259 else
feb11 3:85c6ee25cf3e 260 {
feb11 3:85c6ee25cf3e 261 memset(&buffer[length], 0, 128-length);
feb11 3:85c6ee25cf3e 262 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 3:85c6ee25cf3e 263 memset(buffer, 0, length);
feb11 3:85c6ee25cf3e 264 }
feb11 3:85c6ee25cf3e 265
feb11 0:7a1237bd2d13 266 lengthBit = revWord(lengthBit);
feb11 0:7a1237bd2d13 267 memset(&buffer[112], 0, 8);
feb11 0:7a1237bd2d13 268 memcpy(&buffer[120], &lengthBit, 8);
feb11 0:7a1237bd2d13 269 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 270
feb11 0:7a1237bd2d13 271 h0 = revWord(h0);
feb11 0:7a1237bd2d13 272 h1 = revWord(h1);
feb11 0:7a1237bd2d13 273 h2 = revWord(h2);
feb11 0:7a1237bd2d13 274 h3 = revWord(h3);
feb11 0:7a1237bd2d13 275 h4 = revWord(h4);
feb11 0:7a1237bd2d13 276 h5 = revWord(h5);
feb11 0:7a1237bd2d13 277
feb11 0:7a1237bd2d13 278
feb11 0:7a1237bd2d13 279 memcpy(digest, &h0, 8);
feb11 0:7a1237bd2d13 280 memcpy(&digest[8], &h1, 8);
feb11 0:7a1237bd2d13 281 memcpy(&digest[16], &h2, 8);
feb11 0:7a1237bd2d13 282 memcpy(&digest[24], &h3, 8);
feb11 0:7a1237bd2d13 283 memcpy(&digest[32], &h4, 8);
feb11 0:7a1237bd2d13 284 memcpy(&digest[40], &h5, 8);
feb11 0:7a1237bd2d13 285
feb11 0:7a1237bd2d13 286 if(type == SHA_512)
feb11 0:7a1237bd2d13 287 {
feb11 0:7a1237bd2d13 288 h6 = revWord(h6);
feb11 0:7a1237bd2d13 289 h7 = revWord(h7);
feb11 0:7a1237bd2d13 290 memcpy(&digest[48], &h6, 8);
feb11 0:7a1237bd2d13 291 memcpy(&digest[56], &h7, 8);
feb11 0:7a1237bd2d13 292 }
feb11 0:7a1237bd2d13 293 }
feb11 0:7a1237bd2d13 294