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 14 18:21:32 2013 +0000
Revision:
7:2dbbdfb08123
Child:
10:bc9c23aa3870
added DES (not tested yet)

Who changed what in which revision?

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