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:
2:473bac39ae7c
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 "MD2.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 0:7a1237bd2d13 3
feb11 0:7a1237bd2d13 4 static const uint8_t s[] =
feb11 0:7a1237bd2d13 5 {
feb11 0:7a1237bd2d13 6 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
feb11 0:7a1237bd2d13 7 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
feb11 0:7a1237bd2d13 8 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
feb11 0:7a1237bd2d13 9 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
feb11 0:7a1237bd2d13 10 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
feb11 0:7a1237bd2d13 11 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
feb11 0:7a1237bd2d13 12 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
feb11 0:7a1237bd2d13 13 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
feb11 0:7a1237bd2d13 14 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
feb11 0:7a1237bd2d13 15 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
feb11 0:7a1237bd2d13 16 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
feb11 0:7a1237bd2d13 17 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
feb11 0:7a1237bd2d13 18 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
feb11 0:7a1237bd2d13 19 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
feb11 0:7a1237bd2d13 20 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
feb11 0:7a1237bd2d13 21 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
feb11 0:7a1237bd2d13 22 };
feb11 0:7a1237bd2d13 23
feb11 0:7a1237bd2d13 24
feb11 0:7a1237bd2d13 25 MD2::MD2():
feb11 0:7a1237bd2d13 26 HashAlgorithm(),
feb11 0:7a1237bd2d13 27 bufferLength(0),
feb11 0:7a1237bd2d13 28 l(0)
feb11 0:7a1237bd2d13 29 {
feb11 0:7a1237bd2d13 30 memset(checksum, 0, 16);
feb11 3:85c6ee25cf3e 31 memset(x, 0, 16);
feb11 0:7a1237bd2d13 32 }
feb11 0:7a1237bd2d13 33
feb11 1:14a7cea431aa 34 void MD2::computeBlock(uint8_t *checksum2, uint8_t *x2, uint8_t *l2, uint8_t *buffer2)
feb11 0:7a1237bd2d13 35 {
feb11 3:85c6ee25cf3e 36 if(checksum2 != buffer2)
feb11 0:7a1237bd2d13 37 {
feb11 3:85c6ee25cf3e 38 for(int j = 0; j < 16; ++j)
feb11 3:85c6ee25cf3e 39 {
feb11 3:85c6ee25cf3e 40 uint8_t c = buffer2[j];
feb11 3:85c6ee25cf3e 41 *l2 = (checksum2[j] ^= s[c^(*l2)]);
feb11 3:85c6ee25cf3e 42 }
feb11 0:7a1237bd2d13 43 }
feb11 3:85c6ee25cf3e 44
feb11 2:473bac39ae7c 45 uint32_t *x3 = (uint32_t*)x2;
feb11 2:473bac39ae7c 46 uint32_t *buffer3 = (uint32_t*)buffer2;
feb11 2:473bac39ae7c 47
feb11 2:473bac39ae7c 48 x3[4] = buffer3[0];
feb11 2:473bac39ae7c 49 x3[5] = buffer3[1];
feb11 2:473bac39ae7c 50 x3[6] = buffer3[2];
feb11 2:473bac39ae7c 51 x3[7] = buffer3[3];
feb11 2:473bac39ae7c 52 for(int j = 0; j < 4; ++j)
feb11 2:473bac39ae7c 53 x3[8+j] = x3[4+j] ^ x3[j];
feb11 2:473bac39ae7c 54
feb11 0:7a1237bd2d13 55 uint8_t t = 0;
feb11 0:7a1237bd2d13 56
feb11 0:7a1237bd2d13 57 for(int j = 0; j < 18; ++j)
feb11 0:7a1237bd2d13 58 {
feb11 3:85c6ee25cf3e 59 t = (x2[0] ^= s[t]);
feb11 3:85c6ee25cf3e 60 t = (x2[1] ^= s[t]);
feb11 3:85c6ee25cf3e 61 t = (x2[2] ^= s[t]);
feb11 3:85c6ee25cf3e 62 t = (x2[3] ^= s[t]);
feb11 3:85c6ee25cf3e 63 t = (x2[4] ^= s[t]);
feb11 3:85c6ee25cf3e 64 t = (x2[5] ^= s[t]);
feb11 3:85c6ee25cf3e 65 t = (x2[6] ^= s[t]);
feb11 3:85c6ee25cf3e 66 t = (x2[7] ^= s[t]);
feb11 3:85c6ee25cf3e 67 t = (x2[8] ^= s[t]);
feb11 3:85c6ee25cf3e 68 t = (x2[9] ^= s[t]);
feb11 3:85c6ee25cf3e 69 t = (x2[10] ^= s[t]);
feb11 3:85c6ee25cf3e 70 t = (x2[11] ^= s[t]);
feb11 3:85c6ee25cf3e 71 t = (x2[12] ^= s[t]);
feb11 3:85c6ee25cf3e 72 t = (x2[13] ^= s[t]);
feb11 3:85c6ee25cf3e 73 t = (x2[14] ^= s[t]);
feb11 3:85c6ee25cf3e 74 t = (x2[15] ^= s[t]);
feb11 3:85c6ee25cf3e 75 t = (x2[16] ^= s[t]);
feb11 3:85c6ee25cf3e 76 t = (x2[17] ^= s[t]);
feb11 3:85c6ee25cf3e 77 t = (x2[18] ^= s[t]);
feb11 3:85c6ee25cf3e 78 t = (x2[19] ^= s[t]);
feb11 3:85c6ee25cf3e 79 t = (x2[20] ^= s[t]);
feb11 3:85c6ee25cf3e 80 t = (x2[21] ^= s[t]);
feb11 3:85c6ee25cf3e 81 t = (x2[22] ^= s[t]);
feb11 3:85c6ee25cf3e 82 t = (x2[23] ^= s[t]);
feb11 3:85c6ee25cf3e 83 t = (x2[24] ^= s[t]);
feb11 3:85c6ee25cf3e 84 t = (x2[25] ^= s[t]);
feb11 3:85c6ee25cf3e 85 t = (x2[26] ^= s[t]);
feb11 3:85c6ee25cf3e 86 t = (x2[27] ^= s[t]);
feb11 3:85c6ee25cf3e 87 t = (x2[28] ^= s[t]);
feb11 3:85c6ee25cf3e 88 t = (x2[29] ^= s[t]);
feb11 3:85c6ee25cf3e 89 t = (x2[30] ^= s[t]);
feb11 3:85c6ee25cf3e 90 t = (x2[31] ^= s[t]);
feb11 3:85c6ee25cf3e 91 t = (x2[32] ^= s[t]);
feb11 3:85c6ee25cf3e 92 t = (x2[33] ^= s[t]);
feb11 3:85c6ee25cf3e 93 t = (x2[34] ^= s[t]);
feb11 3:85c6ee25cf3e 94 t = (x2[35] ^= s[t]);
feb11 3:85c6ee25cf3e 95 t = (x2[36] ^= s[t]);
feb11 3:85c6ee25cf3e 96 t = (x2[37] ^= s[t]);
feb11 3:85c6ee25cf3e 97 t = (x2[38] ^= s[t]);
feb11 3:85c6ee25cf3e 98 t = (x2[39] ^= s[t]);
feb11 3:85c6ee25cf3e 99 t = (x2[40] ^= s[t]);
feb11 3:85c6ee25cf3e 100 t = (x2[41] ^= s[t]);
feb11 3:85c6ee25cf3e 101 t = (x2[42] ^= s[t]);
feb11 3:85c6ee25cf3e 102 t = (x2[43] ^= s[t]);
feb11 3:85c6ee25cf3e 103 t = (x2[44] ^= s[t]);
feb11 3:85c6ee25cf3e 104 t = (x2[45] ^= s[t]);
feb11 3:85c6ee25cf3e 105 t = (x2[46] ^= s[t]);
feb11 3:85c6ee25cf3e 106 t = (x2[47] ^= s[t]);
feb11 3:85c6ee25cf3e 107
feb11 0:7a1237bd2d13 108 t += j;
feb11 0:7a1237bd2d13 109 }
feb11 0:7a1237bd2d13 110 }
feb11 0:7a1237bd2d13 111
feb11 0:7a1237bd2d13 112 void MD2::add(uint8_t *in, uint32_t length)
feb11 3:85c6ee25cf3e 113 {
feb11 3:85c6ee25cf3e 114 if(bufferLength == 0)
feb11 3:85c6ee25cf3e 115 {
feb11 3:85c6ee25cf3e 116 while(length >= 16)
feb11 3:85c6ee25cf3e 117 {
feb11 3:85c6ee25cf3e 118 computeBlock(checksum, x, &l, in);
feb11 3:85c6ee25cf3e 119 length -= 16;
feb11 3:85c6ee25cf3e 120 in += 16;
feb11 3:85c6ee25cf3e 121 }
feb11 3:85c6ee25cf3e 122 bufferLength = length;
feb11 3:85c6ee25cf3e 123 memcpy(buffer, in, length);
feb11 3:85c6ee25cf3e 124 }
feb11 3:85c6ee25cf3e 125 else if(length < 16-bufferLength)
feb11 0:7a1237bd2d13 126 {
feb11 0:7a1237bd2d13 127 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 128 bufferLength += length;
feb11 0:7a1237bd2d13 129 }
feb11 3:85c6ee25cf3e 130 else
feb11 0:7a1237bd2d13 131 {
feb11 3:85c6ee25cf3e 132 int offset = 16-bufferLength;
feb11 3:85c6ee25cf3e 133 memcpy(&buffer[bufferLength], in, offset);
feb11 1:14a7cea431aa 134 computeBlock(checksum, x, &l, buffer);
feb11 3:85c6ee25cf3e 135 in += offset;
feb11 3:85c6ee25cf3e 136 length -= offset;
feb11 3:85c6ee25cf3e 137 while(length >= 16)
feb11 3:85c6ee25cf3e 138 {
feb11 3:85c6ee25cf3e 139 computeBlock(checksum, x, &l, in);
feb11 3:85c6ee25cf3e 140 in += 16;
feb11 3:85c6ee25cf3e 141 length -= 16;
feb11 3:85c6ee25cf3e 142 }
feb11 3:85c6ee25cf3e 143 bufferLength = length;
feb11 3:85c6ee25cf3e 144 memcpy(buffer, &in, length);
feb11 0:7a1237bd2d13 145 }
feb11 3:85c6ee25cf3e 146
feb11 0:7a1237bd2d13 147 }
feb11 0:7a1237bd2d13 148
feb11 0:7a1237bd2d13 149 void MD2::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 150 {
feb11 0:7a1237bd2d13 151 // compute what's left in the buffer
feb11 0:7a1237bd2d13 152 int padding = 16 - bufferLength;
feb11 0:7a1237bd2d13 153 memset(&buffer[bufferLength], padding, padding);
feb11 1:14a7cea431aa 154 computeBlock(checksum, x, &l, buffer);
feb11 3:85c6ee25cf3e 155 computeBlock(checksum, x, &l, checksum);
feb11 3:85c6ee25cf3e 156 memcpy(digest, x, 16);
feb11 0:7a1237bd2d13 157
feb11 3:85c6ee25cf3e 158 uint32_t *x2 = (uint32_t*)x;
feb11 3:85c6ee25cf3e 159 uint32_t *checksum2 = (uint32_t*)checksum;
feb11 3:85c6ee25cf3e 160
feb11 0:7a1237bd2d13 161 // reset state
feb11 0:7a1237bd2d13 162 bufferLength = 0;
feb11 0:7a1237bd2d13 163 l = 0;
feb11 3:85c6ee25cf3e 164 checksum2[0] = x2[0] = 0;
feb11 3:85c6ee25cf3e 165 checksum2[1] = x2[1] = 0;
feb11 3:85c6ee25cf3e 166 checksum2[2] = x2[2] = 0;
feb11 3:85c6ee25cf3e 167 checksum2[3] = x2[3] = 0;
feb11 0:7a1237bd2d13 168 }
feb11 0:7a1237bd2d13 169
feb11 0:7a1237bd2d13 170 uint8_t MD2::outputSize() const
feb11 0:7a1237bd2d13 171 {
feb11 0:7a1237bd2d13 172 return 16;
feb11 0:7a1237bd2d13 173 }
feb11 0:7a1237bd2d13 174
feb11 0:7a1237bd2d13 175 void MD2::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 176 {
feb11 3:85c6ee25cf3e 177 uint8_t x[48];
feb11 3:85c6ee25cf3e 178 uint8_t checksum[16];
feb11 3:85c6ee25cf3e 179 uint8_t buffer[16];
feb11 3:85c6ee25cf3e 180 memset(x, 0, 16);
feb11 3:85c6ee25cf3e 181 memset(checksum, 0, 16);
feb11 1:14a7cea431aa 182 uint8_t l = 0;
feb11 3:85c6ee25cf3e 183 while(length >= 16)
feb11 0:7a1237bd2d13 184 {
feb11 3:85c6ee25cf3e 185 computeBlock(checksum, x, &l, in);
feb11 3:85c6ee25cf3e 186 length -= 16;
feb11 3:85c6ee25cf3e 187 in += 16;
feb11 1:14a7cea431aa 188 }
feb11 1:14a7cea431aa 189
feb11 3:85c6ee25cf3e 190 memcpy(buffer, in, length);
feb11 3:85c6ee25cf3e 191 uint8_t padding = 16-length;
feb11 3:85c6ee25cf3e 192 memset(&buffer[length], padding, padding);
feb11 1:14a7cea431aa 193 computeBlock(checksum, x, &l, buffer);
feb11 3:85c6ee25cf3e 194 computeBlock(checksum,x, &l, checksum);
feb11 0:7a1237bd2d13 195 memcpy(digest, x, 16);
feb11 0:7a1237bd2d13 196 }