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:
Sun May 11 13:36:45 2014 +0000
Revision:
14:f04410cef037
Parent:
13:ac8e23b98dae
CBC mode completed

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 13:ac8e23b98dae 58 else if((int)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 13:ac8e23b98dae 126 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 127 __forceinline
feb11 13:ac8e23b98dae 128 #endif
feb11 13:ac8e23b98dae 129 void MD2::computeBlock(uint8_t *checksum2, uint8_t *x2, uint8_t *l2, uint8_t *buffer2)
feb11 7:2dbbdfb08123 130 {
feb11 7:2dbbdfb08123 131 if(checksum2 != buffer2)
feb11 7:2dbbdfb08123 132 {
feb11 13:ac8e23b98dae 133 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 134 #pragma unroll_completely
feb11 13:ac8e23b98dae 135 #endif
feb11 7:2dbbdfb08123 136 for(int j = 0; j < 16; ++j)
feb11 7:2dbbdfb08123 137 {
feb11 7:2dbbdfb08123 138 uint8_t c = buffer2[j];
feb11 7:2dbbdfb08123 139 *l2 = (checksum2[j] ^= s[c^(*l2)]);
feb11 7:2dbbdfb08123 140 }
feb11 7:2dbbdfb08123 141 }
feb11 7:2dbbdfb08123 142
feb11 7:2dbbdfb08123 143 uint32_t *x3 = (uint32_t*)x2;
feb11 7:2dbbdfb08123 144 uint32_t *buffer3 = (uint32_t*)buffer2;
feb11 7:2dbbdfb08123 145
feb11 7:2dbbdfb08123 146 x3[4] = buffer3[0];
feb11 7:2dbbdfb08123 147 x3[5] = buffer3[1];
feb11 7:2dbbdfb08123 148 x3[6] = buffer3[2];
feb11 7:2dbbdfb08123 149 x3[7] = buffer3[3];
feb11 7:2dbbdfb08123 150 for(int j = 0; j < 4; ++j)
feb11 7:2dbbdfb08123 151 x3[8+j] = x3[4+j] ^ x3[j];
feb11 7:2dbbdfb08123 152
feb11 7:2dbbdfb08123 153 uint8_t t = 0;
feb11 13:ac8e23b98dae 154 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 155 #pragma unroll_completely
feb11 13:ac8e23b98dae 156 #endif
feb11 7:2dbbdfb08123 157 for(int j = 0; j < 18; ++j)
feb11 7:2dbbdfb08123 158 {
feb11 7:2dbbdfb08123 159 t = (x2[0] ^= s[t]);
feb11 7:2dbbdfb08123 160 t = (x2[1] ^= s[t]);
feb11 7:2dbbdfb08123 161 t = (x2[2] ^= s[t]);
feb11 7:2dbbdfb08123 162 t = (x2[3] ^= s[t]);
feb11 7:2dbbdfb08123 163 t = (x2[4] ^= s[t]);
feb11 7:2dbbdfb08123 164 t = (x2[5] ^= s[t]);
feb11 7:2dbbdfb08123 165 t = (x2[6] ^= s[t]);
feb11 7:2dbbdfb08123 166 t = (x2[7] ^= s[t]);
feb11 7:2dbbdfb08123 167 t = (x2[8] ^= s[t]);
feb11 7:2dbbdfb08123 168 t = (x2[9] ^= s[t]);
feb11 7:2dbbdfb08123 169 t = (x2[10] ^= s[t]);
feb11 7:2dbbdfb08123 170 t = (x2[11] ^= s[t]);
feb11 7:2dbbdfb08123 171 t = (x2[12] ^= s[t]);
feb11 7:2dbbdfb08123 172 t = (x2[13] ^= s[t]);
feb11 7:2dbbdfb08123 173 t = (x2[14] ^= s[t]);
feb11 7:2dbbdfb08123 174 t = (x2[15] ^= s[t]);
feb11 7:2dbbdfb08123 175 t = (x2[16] ^= s[t]);
feb11 7:2dbbdfb08123 176 t = (x2[17] ^= s[t]);
feb11 7:2dbbdfb08123 177 t = (x2[18] ^= s[t]);
feb11 7:2dbbdfb08123 178 t = (x2[19] ^= s[t]);
feb11 7:2dbbdfb08123 179 t = (x2[20] ^= s[t]);
feb11 7:2dbbdfb08123 180 t = (x2[21] ^= s[t]);
feb11 7:2dbbdfb08123 181 t = (x2[22] ^= s[t]);
feb11 7:2dbbdfb08123 182 t = (x2[23] ^= s[t]);
feb11 7:2dbbdfb08123 183 t = (x2[24] ^= s[t]);
feb11 7:2dbbdfb08123 184 t = (x2[25] ^= s[t]);
feb11 7:2dbbdfb08123 185 t = (x2[26] ^= s[t]);
feb11 7:2dbbdfb08123 186 t = (x2[27] ^= s[t]);
feb11 7:2dbbdfb08123 187 t = (x2[28] ^= s[t]);
feb11 7:2dbbdfb08123 188 t = (x2[29] ^= s[t]);
feb11 7:2dbbdfb08123 189 t = (x2[30] ^= s[t]);
feb11 7:2dbbdfb08123 190 t = (x2[31] ^= s[t]);
feb11 7:2dbbdfb08123 191 t = (x2[32] ^= s[t]);
feb11 7:2dbbdfb08123 192 t = (x2[33] ^= s[t]);
feb11 7:2dbbdfb08123 193 t = (x2[34] ^= s[t]);
feb11 7:2dbbdfb08123 194 t = (x2[35] ^= s[t]);
feb11 7:2dbbdfb08123 195 t = (x2[36] ^= s[t]);
feb11 7:2dbbdfb08123 196 t = (x2[37] ^= s[t]);
feb11 7:2dbbdfb08123 197 t = (x2[38] ^= s[t]);
feb11 7:2dbbdfb08123 198 t = (x2[39] ^= s[t]);
feb11 7:2dbbdfb08123 199 t = (x2[40] ^= s[t]);
feb11 7:2dbbdfb08123 200 t = (x2[41] ^= s[t]);
feb11 7:2dbbdfb08123 201 t = (x2[42] ^= s[t]);
feb11 7:2dbbdfb08123 202 t = (x2[43] ^= s[t]);
feb11 7:2dbbdfb08123 203 t = (x2[44] ^= s[t]);
feb11 7:2dbbdfb08123 204 t = (x2[45] ^= s[t]);
feb11 7:2dbbdfb08123 205 t = (x2[46] ^= s[t]);
feb11 7:2dbbdfb08123 206 t = (x2[47] ^= s[t]);
feb11 10:bc9c23aa3870 207
feb11 7:2dbbdfb08123 208 t += j;
feb11 7:2dbbdfb08123 209 }
feb11 7:2dbbdfb08123 210 }