mirror of
https://github.com/darlinghq/darling-corecrypto.git
synced 2024-11-23 12:19:44 +00:00
176 lines
5.5 KiB
C
176 lines
5.5 KiB
C
/*
|
|
* Copyright (c) 2016 Lubos Dolezel
|
|
*
|
|
* This file is part of Darling CoreCrypto.
|
|
*
|
|
* Darling is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <corecrypto/ccdigest.h>
|
|
#include <corecrypto/ccdigest_priv.h>
|
|
#include <corecrypto/ccmd5.h>
|
|
#include <corecrypto/cc_priv.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
static void md5_final(const struct ccdigest_info* di, ccdigest_ctx_t ctx, unsigned char* out);
|
|
static void md5_compress(ccdigest_state_t state, size_t nblocks, const void* in);
|
|
|
|
static const uint32_t md5_initial_state[4+18] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
|
|
|
|
const struct ccdigest_info ccmd5_ltc_di = {
|
|
.initial_state = md5_initial_state,
|
|
.compress = md5_compress,
|
|
.final = ccdigest_final_64le,
|
|
.output_size = CCMD5_OUTPUT_SIZE,
|
|
.state_size = CCMD5_STATE_SIZE,
|
|
.block_size = CCMD5_BLOCK_SIZE,
|
|
.oid = CC_DIGEST_OID_MD5,
|
|
.oid_size = 10,
|
|
};
|
|
|
|
typedef uint32_t UINT4;
|
|
|
|
/* ROTATE_LEFT rotates x left n bits.
|
|
*/
|
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
|
|
|
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
|
Rotation is separate from addition to prevent recomputation.
|
|
*/
|
|
#define FF(a, b, c, d, x, s, ac) { \
|
|
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
(a) = ROTATE_LEFT ((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define GG(a, b, c, d, x, s, ac) { \
|
|
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
(a) = ROTATE_LEFT ((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define HH(a, b, c, d, x, s, ac) { \
|
|
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
(a) = ROTATE_LEFT ((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
#define II(a, b, c, d, x, s, ac) { \
|
|
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
(a) = ROTATE_LEFT ((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
|
|
|
static void md5_compress(ccdigest_state_t state, size_t nblocks, const void* in)
|
|
{
|
|
uint32_t W[16];
|
|
uint32_t a, b, c, d;
|
|
uint32_t* s = ccdigest_u32(state);
|
|
const uint8_t* buf = in;
|
|
|
|
for (size_t block = 0; block < nblocks; block++)
|
|
{
|
|
/* copy the state into 512-bits into W[0..15] */
|
|
for (int i = 0; i < 16; i++)
|
|
CC_LOAD32_LE(W[i], buf + (4*i));
|
|
|
|
/* copy state */
|
|
a = s[0];
|
|
b = s[1];
|
|
c = s[2];
|
|
d = s[3];
|
|
|
|
FF(a,b,c,d,W[0],7,0xd76aa478)
|
|
FF(d,a,b,c,W[1],12,0xe8c7b756)
|
|
FF(c,d,a,b,W[2],17,0x242070db)
|
|
FF(b,c,d,a,W[3],22,0xc1bdceee)
|
|
FF(a,b,c,d,W[4],7,0xf57c0faf)
|
|
FF(d,a,b,c,W[5],12,0x4787c62a)
|
|
FF(c,d,a,b,W[6],17,0xa8304613)
|
|
FF(b,c,d,a,W[7],22,0xfd469501)
|
|
FF(a,b,c,d,W[8],7,0x698098d8)
|
|
FF(d,a,b,c,W[9],12,0x8b44f7af)
|
|
FF(c,d,a,b,W[10],17,0xffff5bb1)
|
|
FF(b,c,d,a,W[11],22,0x895cd7be)
|
|
FF(a,b,c,d,W[12],7,0x6b901122)
|
|
FF(d,a,b,c,W[13],12,0xfd987193)
|
|
FF(c,d,a,b,W[14],17,0xa679438e)
|
|
FF(b,c,d,a,W[15],22,0x49b40821)
|
|
GG(a,b,c,d,W[1],5,0xf61e2562)
|
|
GG(d,a,b,c,W[6],9,0xc040b340)
|
|
GG(c,d,a,b,W[11],14,0x265e5a51)
|
|
GG(b,c,d,a,W[0],20,0xe9b6c7aa)
|
|
GG(a,b,c,d,W[5],5,0xd62f105d)
|
|
GG(d,a,b,c,W[10],9,0x02441453)
|
|
GG(c,d,a,b,W[15],14,0xd8a1e681)
|
|
GG(b,c,d,a,W[4],20,0xe7d3fbc8)
|
|
GG(a,b,c,d,W[9],5,0x21e1cde6)
|
|
GG(d,a,b,c,W[14],9,0xc33707d6)
|
|
GG(c,d,a,b,W[3],14,0xf4d50d87)
|
|
GG(b,c,d,a,W[8],20,0x455a14ed)
|
|
GG(a,b,c,d,W[13],5,0xa9e3e905)
|
|
GG(d,a,b,c,W[2],9,0xfcefa3f8)
|
|
GG(c,d,a,b,W[7],14,0x676f02d9)
|
|
GG(b,c,d,a,W[12],20,0x8d2a4c8a)
|
|
HH(a,b,c,d,W[5],4,0xfffa3942)
|
|
HH(d,a,b,c,W[8],11,0x8771f681)
|
|
HH(c,d,a,b,W[11],16,0x6d9d6122)
|
|
HH(b,c,d,a,W[14],23,0xfde5380c)
|
|
HH(a,b,c,d,W[1],4,0xa4beea44)
|
|
HH(d,a,b,c,W[4],11,0x4bdecfa9)
|
|
HH(c,d,a,b,W[7],16,0xf6bb4b60)
|
|
HH(b,c,d,a,W[10],23,0xbebfbc70)
|
|
HH(a,b,c,d,W[13],4,0x289b7ec6)
|
|
HH(d,a,b,c,W[0],11,0xeaa127fa)
|
|
HH(c,d,a,b,W[3],16,0xd4ef3085)
|
|
HH(b,c,d,a,W[6],23,0x04881d05)
|
|
HH(a,b,c,d,W[9],4,0xd9d4d039)
|
|
HH(d,a,b,c,W[12],11,0xe6db99e5)
|
|
HH(c,d,a,b,W[15],16,0x1fa27cf8)
|
|
HH(b,c,d,a,W[2],23,0xc4ac5665)
|
|
II(a,b,c,d,W[0],6,0xf4292244)
|
|
II(d,a,b,c,W[7],10,0x432aff97)
|
|
II(c,d,a,b,W[14],15,0xab9423a7)
|
|
II(b,c,d,a,W[5],21,0xfc93a039)
|
|
II(a,b,c,d,W[12],6,0x655b59c3)
|
|
II(d,a,b,c,W[3],10,0x8f0ccc92)
|
|
II(c,d,a,b,W[10],15,0xffeff47d)
|
|
II(b,c,d,a,W[1],21,0x85845dd1)
|
|
II(a,b,c,d,W[8],6,0x6fa87e4f)
|
|
II(d,a,b,c,W[15],10,0xfe2ce6e0)
|
|
II(c,d,a,b,W[6],15,0xa3014314)
|
|
II(b,c,d,a,W[13],21,0x4e0811a1)
|
|
II(a,b,c,d,W[4],6,0xf7537e82)
|
|
II(d,a,b,c,W[11],10,0xbd3af235)
|
|
II(c,d,a,b,W[2],15,0x2ad7d2bb)
|
|
II(b,c,d,a,W[9],21,0xeb86d391)
|
|
|
|
s[0] += a;
|
|
s[1] += b;
|
|
s[2] += c;
|
|
s[3] += d;
|
|
|
|
buf += CCMD5_BLOCK_SIZE;
|
|
}
|
|
}
|
|
|
|
const struct ccdigest_info *ccmd5_di(void) {
|
|
return &ccmd5_ltc_di;
|
|
}
|
|
|