1/* 2 * md5.c 3 * Adapted for perf_index from ccmd5_ltc.c in corecrypto 4 * 5 * Created by Fabrice Gautier on 12/3/10. 6 * Copyright 2010,2011 Apple Inc. All rights reserved. 7 * 8 */ 9 10#include "md5.h" 11 12#include <stdint.h> 13#include <string.h> 14 15#define CCMD5_BLOCK_SIZE 64 16 17#define F(x,y,z) (z ^ (x & (y ^ z))) 18#define G(x,y,z) (y ^ (z & (y ^ x))) 19#define H(x,y,z) (x^y^z) 20#define I(x,y,z) (y^(x|(~z))) 21 22#define CC_ROLc(X,s) (((X) << (s)) | ((X) >> (32 - (s)))) 23 24#define FF(a,b,c,d,M,s,t) \ 25a = (a + F(b,c,d) + M + t); a = CC_ROLc(a, s) + b; 26 27#define GG(a,b,c,d,M,s,t) \ 28a = (a + G(b,c,d) + M + t); a = CC_ROLc(a, s) + b; 29 30#define HH(a,b,c,d,M,s,t) \ 31a = (a + H(b,c,d) + M + t); a = CC_ROLc(a, s) + b; 32 33#define II(a,b,c,d,M,s,t) \ 34a = (a + I(b,c,d) + M + t); a = CC_ROLc(a, s) + b; 35 36static void md5_compress(uint32_t *state, unsigned long nblocks, const void *in) 37{ 38 uint32_t i, W[16], a, b, c, d; 39 uint32_t *s = state; 40 const unsigned char *buf = in; 41 42 while(nblocks--) { 43 44 /* copy the state into 512-bits into W[0..15] */ 45 for (i = 0; i < 16; i++) { 46 W[i] = ((uint32_t*)buf)[i]; 47 } 48 49 /* copy state */ 50 a = s[0]; 51 b = s[1]; 52 c = s[2]; 53 d = s[3]; 54 55 FF(a,b,c,d,W[0],7,0xd76aa478) 56 FF(d,a,b,c,W[1],12,0xe8c7b756) 57 FF(c,d,a,b,W[2],17,0x242070db) 58 FF(b,c,d,a,W[3],22,0xc1bdceee) 59 FF(a,b,c,d,W[4],7,0xf57c0faf) 60 FF(d,a,b,c,W[5],12,0x4787c62a) 61 FF(c,d,a,b,W[6],17,0xa8304613) 62 FF(b,c,d,a,W[7],22,0xfd469501) 63 FF(a,b,c,d,W[8],7,0x698098d8) 64 FF(d,a,b,c,W[9],12,0x8b44f7af) 65 FF(c,d,a,b,W[10],17,0xffff5bb1) 66 FF(b,c,d,a,W[11],22,0x895cd7be) 67 FF(a,b,c,d,W[12],7,0x6b901122) 68 FF(d,a,b,c,W[13],12,0xfd987193) 69 FF(c,d,a,b,W[14],17,0xa679438e) 70 FF(b,c,d,a,W[15],22,0x49b40821) 71 GG(a,b,c,d,W[1],5,0xf61e2562) 72 GG(d,a,b,c,W[6],9,0xc040b340) 73 GG(c,d,a,b,W[11],14,0x265e5a51) 74 GG(b,c,d,a,W[0],20,0xe9b6c7aa) 75 GG(a,b,c,d,W[5],5,0xd62f105d) 76 GG(d,a,b,c,W[10],9,0x02441453) 77 GG(c,d,a,b,W[15],14,0xd8a1e681) 78 GG(b,c,d,a,W[4],20,0xe7d3fbc8) 79 GG(a,b,c,d,W[9],5,0x21e1cde6) 80 GG(d,a,b,c,W[14],9,0xc33707d6) 81 GG(c,d,a,b,W[3],14,0xf4d50d87) 82 GG(b,c,d,a,W[8],20,0x455a14ed) 83 GG(a,b,c,d,W[13],5,0xa9e3e905) 84 GG(d,a,b,c,W[2],9,0xfcefa3f8) 85 GG(c,d,a,b,W[7],14,0x676f02d9) 86 GG(b,c,d,a,W[12],20,0x8d2a4c8a) 87 HH(a,b,c,d,W[5],4,0xfffa3942) 88 HH(d,a,b,c,W[8],11,0x8771f681) 89 HH(c,d,a,b,W[11],16,0x6d9d6122) 90 HH(b,c,d,a,W[14],23,0xfde5380c) 91 HH(a,b,c,d,W[1],4,0xa4beea44) 92 HH(d,a,b,c,W[4],11,0x4bdecfa9) 93 HH(c,d,a,b,W[7],16,0xf6bb4b60) 94 HH(b,c,d,a,W[10],23,0xbebfbc70) 95 HH(a,b,c,d,W[13],4,0x289b7ec6) 96 HH(d,a,b,c,W[0],11,0xeaa127fa) 97 HH(c,d,a,b,W[3],16,0xd4ef3085) 98 HH(b,c,d,a,W[6],23,0x04881d05) 99 HH(a,b,c,d,W[9],4,0xd9d4d039) 100 HH(d,a,b,c,W[12],11,0xe6db99e5) 101 HH(c,d,a,b,W[15],16,0x1fa27cf8) 102 HH(b,c,d,a,W[2],23,0xc4ac5665) 103 II(a,b,c,d,W[0],6,0xf4292244) 104 II(d,a,b,c,W[7],10,0x432aff97) 105 II(c,d,a,b,W[14],15,0xab9423a7) 106 II(b,c,d,a,W[5],21,0xfc93a039) 107 II(a,b,c,d,W[12],6,0x655b59c3) 108 II(d,a,b,c,W[3],10,0x8f0ccc92) 109 II(c,d,a,b,W[10],15,0xffeff47d) 110 II(b,c,d,a,W[1],21,0x85845dd1) 111 II(a,b,c,d,W[8],6,0x6fa87e4f) 112 II(d,a,b,c,W[15],10,0xfe2ce6e0) 113 II(c,d,a,b,W[6],15,0xa3014314) 114 II(b,c,d,a,W[13],21,0x4e0811a1) 115 II(a,b,c,d,W[4],6,0xf7537e82) 116 II(d,a,b,c,W[11],10,0xbd3af235) 117 II(c,d,a,b,W[2],15,0x2ad7d2bb) 118 II(b,c,d,a,W[9],21,0xeb86d391) 119 120 /* store state */ 121 s[0] += a; 122 s[1] += b; 123 s[2] += c; 124 s[3] += d; 125 126 buf+=CCMD5_BLOCK_SIZE; 127 } 128} 129 130void md5_hash(uint8_t *message, uint64_t len, uint32_t *hash) { 131 hash[0] = 0x67452301; 132 hash[1] = 0xEFCDAB89; 133 hash[2] = 0x98BADCFE; 134 hash[3] = 0x10325476; 135 136 md5_compress(hash, len/64, message); 137 138 uint32_t blockbuff[16]; 139 uint8_t *byteptr = (uint8_t*)blockbuff; 140 141 int left = len % 64; 142 memcpy(byteptr, message + len-left, left); 143 144 byteptr[left] = 0x80; 145 left++; 146 if (64 - left >= 8) 147 bzero(byteptr + left, 56 - left); 148 else { 149 memset(byteptr + left, 0, 64 - left); 150 md5_compress(hash, 1, blockbuff); 151 bzero(blockbuff, 56); 152 } 153 blockbuff[14] = (uint32_t)(len << 3); 154 blockbuff[15] = (uint32_t)(len >> 29); 155 md5_compress(hash, 1, blockbuff); 156} 157