Skip to content

Instantly share code, notes, and snippets.

@mniip
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mniip/1b168b30c5d15143ffac to your computer and use it in GitHub Desktop.
Save mniip/1b168b30c5d15143ffac to your computer and use it in GitHub Desktop.
// extern void md5(char *digest, const char *data, size_t length)
.global md5
.type md5 @function
md5:
pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
push %rbp
movq %rsp, %rbp
// %rdi - digest
// %rsi - data
// %rdx - length
movq %rdx, %rcx
addq $0x48, %rdx
andq $0xFFFFFFFFFFFFFFC0, %rdx
subq %rdx, %rsp
movq %rcx, %rax
shlq $3, %rax
movq %rax, -0x8(%rbp)
movq %rdi, %rbx
movq %rsp, %rdi
rep movsb
movb $0x80, (%rdi)
addq $1, %rdi
movq %rbp, %rcx
subq %rdi, %rcx
subq $8, %rcx
movb $0, %al
rep stosb
movq %rbx, %rdi
// %rsp - block
// %r8d, %r9d, %r10d, %r11d - A, B, C, D
// %r12d, %r13d, %r14d. %r15d - A0, B0, C0, D0
movl $0x67452301, %r12d
movl $0xEFCDAB89, %r13d
movl $0x98BADCFE, %r14d
movl $0x10325476, %r15d
round:
movl %r12d, %r8d
movl %r13d, %r9d
movl %r14d, %r10d
movl %r15d, %r11d
// M = N + (M + K + F(N, O, P) + block[B]) <<< S
.macro iteration F, M, N, O, P, K, B, S
\F \N, \O, \P
.ifge \K-0x80000000
leal \K-0x100000000(\M, %eax, 1), %eax
.else
leal \K(\M, %eax, 1), %eax
.endif
addl \B*4(%rsp), %eax
roll $\S, %eax
leal (\N, %eax, 1), \M
.endm
// (N & O) | (~N & P)
.macro func1 N, O, P
movl \N, %eax
notl %eax
andl \P, %eax
movl \N, %ebx
andl \O, %ebx
orl %ebx, %eax
.endm
iteration func1, %r8d, %r9d, %r10d, %r11d, 0xD76AA478, 0, 7
iteration func1, %r11d, %r8d, %r9d, %r10d, 0xE8C7B756, 1, 12
iteration func1, %r10d, %r11d, %r8d, %r9d, 0x242070DB, 2, 17
iteration func1, %r9d, %r10d, %r11d, %r8d, 0xC1BDCEEE, 3, 22
iteration func1, %r8d, %r9d, %r10d, %r11d, 0xF57C0FAF, 4, 7
iteration func1, %r11d, %r8d, %r9d, %r10d, 0x4787C62A, 5, 12
iteration func1, %r10d, %r11d, %r8d, %r9d, 0xA8304613, 6, 17
iteration func1, %r9d, %r10d, %r11d, %r8d, 0xFD469501, 7, 22
iteration func1, %r8d, %r9d, %r10d, %r11d, 0x698098D8, 8, 7
iteration func1, %r11d, %r8d, %r9d, %r10d, 0x8B44F7AF, 9, 12
iteration func1, %r10d, %r11d, %r8d, %r9d, 0xFFFF5BB1, 10, 17
iteration func1, %r9d, %r10d, %r11d, %r8d, 0x895CD7BE, 11, 22
iteration func1, %r8d, %r9d, %r10d, %r11d, 0x6B901122, 12, 7
iteration func1, %r11d, %r8d, %r9d, %r10d, 0xFD987193, 13, 12
iteration func1, %r10d, %r11d, %r8d, %r9d, 0xA679438E, 14, 17
iteration func1, %r9d, %r10d, %r11d, %r8d, 0x49B40821, 15, 22
// (P & N) | (~P & O)
.macro func2 N, O, P
func1 \P, \N, \O
.endm
iteration func2, %r8d, %r9d, %r10d, %r11d, 0xF61E2562, 1, 5
iteration func2, %r11d, %r8d, %r9d, %r10d, 0xC040B340, 6, 9
iteration func2, %r10d, %r11d, %r8d, %r9d, 0x265E5A51, 11, 14
iteration func2, %r9d, %r10d, %r11d, %r8d, 0xE9B6C7AA, 0, 20
iteration func2, %r8d, %r9d, %r10d, %r11d, 0xD62F105D, 5, 5
iteration func2, %r11d, %r8d, %r9d, %r10d, 0x02441453, 10, 9
iteration func2, %r10d, %r11d, %r8d, %r9d, 0xD8A1E681, 15, 14
iteration func2, %r9d, %r10d, %r11d, %r8d, 0xE7D3FBC8, 4, 20
iteration func2, %r8d, %r9d, %r10d, %r11d, 0x21E1CDE6, 9, 5
iteration func2, %r11d, %r8d, %r9d, %r10d, 0xC33707D6, 14, 9
iteration func2, %r10d, %r11d, %r8d, %r9d, 0xF4D50D87, 3, 14
iteration func2, %r9d, %r10d, %r11d, %r8d, 0x455A14ED, 8, 20
iteration func2, %r8d, %r9d, %r10d, %r11d, 0xA9E3E905, 13, 5
iteration func2, %r11d, %r8d, %r9d, %r10d, 0xFCEFA3F8, 2, 9
iteration func2, %r10d, %r11d, %r8d, %r9d, 0x676F02D9, 7, 14
iteration func2, %r9d, %r10d, %r11d, %r8d, 0x8D2A4C8A, 12, 20
// (N ^ O ^ P)
.macro func3 N, O, P
movl \N, %eax
xorl \O, %eax
xorl \P, %eax
.endm
iteration func3, %r8d, %r9d, %r10d, %r11d, 0xFFFA3942, 5, 4
iteration func3, %r11d, %r8d, %r9d, %r10d, 0x8771F681, 8, 11
iteration func3, %r10d, %r11d, %r8d, %r9d, 0x6D9D6122, 11, 16
iteration func3, %r9d, %r10d, %r11d, %r8d, 0xFDE5380C, 14, 23
iteration func3, %r8d, %r9d, %r10d, %r11d, 0xA4BEEA44, 1, 4
iteration func3, %r11d, %r8d, %r9d, %r10d, 0x4BDECFA9, 4, 11
iteration func3, %r10d, %r11d, %r8d, %r9d, 0xF6BB4B60, 7, 16
iteration func3, %r9d, %r10d, %r11d, %r8d, 0xBEBFBC70, 10, 23
iteration func3, %r8d, %r9d, %r10d, %r11d, 0x289B7EC6, 13, 4
iteration func3, %r11d, %r8d, %r9d, %r10d, 0xEAA127FA, 0, 11
iteration func3, %r10d, %r11d, %r8d, %r9d, 0xD4EF3085, 3, 16
iteration func3, %r9d, %r10d, %r11d, %r8d, 0x04881D05, 6, 23
iteration func3, %r8d, %r9d, %r10d, %r11d, 0xD9D4D039, 9, 4
iteration func3, %r11d, %r8d, %r9d, %r10d, 0xE6DB99E5, 12, 11
iteration func3, %r10d, %r11d, %r8d, %r9d, 0x1FA27CF8, 15, 16
iteration func3, %r9d, %r10d, %r11d, %r8d, 0xC4AC5665, 2, 23
// (O ^ (N | ~P))
.macro func4 N, O, P
movl \P, %eax
notl %eax
orl \N, %eax
xorl \O, %eax
.endm
iteration func4, %r8d, %r9d, %r10d, %r11d, 0xF4292244, 0, 6
iteration func4, %r11d, %r8d, %r9d, %r10d, 0x432AFF97, 7, 10
iteration func4, %r10d, %r11d, %r8d, %r9d, 0xAB9423A7, 14, 15
iteration func4, %r9d, %r10d, %r11d, %r8d, 0xFC93A039, 5, 21
iteration func4, %r8d, %r9d, %r10d, %r11d, 0x655B59C3, 12, 6
iteration func4, %r11d, %r8d, %r9d, %r10d, 0x8F0CCC92, 3, 10
iteration func4, %r10d, %r11d, %r8d, %r9d, 0xFFEFF47D, 10, 15
iteration func4, %r9d, %r10d, %r11d, %r8d, 0x85845DD1, 1, 21
iteration func4, %r8d, %r9d, %r10d, %r11d, 0x6FA87E4F, 8, 6
iteration func4, %r11d, %r8d, %r9d, %r10d, 0xFE2CE6E0, 15, 10
iteration func4, %r10d, %r11d, %r8d, %r9d, 0xA3014314, 6, 15
iteration func4, %r9d, %r10d, %r11d, %r8d, 0x4E0811A1, 13, 21
iteration func4, %r8d, %r9d, %r10d, %r11d, 0xF7537E82, 4, 6
iteration func4, %r11d, %r8d, %r9d, %r10d, 0xBD3AF235, 11, 10
iteration func4, %r10d, %r11d, %r8d, %r9d, 0x2AD7D2BB, 2, 15
iteration func4, %r9d, %r10d, %r11d, %r8d, 0xEB86D391, 9, 21
addl %r8d, %r12d
addl %r9d, %r13d
addl %r10d, %r14d
addl %r11d, %r15d
addq $0x40, %rsp
cmpq %rsp, %rbp
jne round
movl %r12d, 0(%rdi)
movl %r13d, 4(%rdi)
movl %r14d, 8(%rdi)
movl %r15d, 12(%rdi)
leave
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbx
retq
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
inline unsigned int lrot(unsigned int x, unsigned int s) { return (x << s) | (x >> 32 - s); }
void block_round(unsigned int *A0, unsigned int *B0, unsigned int *C0, unsigned int *D0, unsigned int *block)
{
unsigned int A = *A0;
unsigned int B = *B0;
unsigned int C = *C0;
unsigned int D = *D0;
#define R1(N, O, P) ((N & O) | (~N & P))
A = B + lrot(A + 0xD76AA478 + R1(B, C, D) + block[0], 7);
D = A + lrot(D + 0xE8C7B756 + R1(A, B, C) + block[1], 12);
C = D + lrot(C + 0x242070DB + R1(D, A, B) + block[2], 17);
B = C + lrot(B + 0xC1BDCEEE + R1(C, D, A) + block[3], 22);
A = B + lrot(A + 0xF57C0FAF + R1(B, C, D) + block[4], 7);
D = A + lrot(D + 0x4787C62A + R1(A, B, C) + block[5], 12);
C = D + lrot(C + 0xA8304613 + R1(D, A, B) + block[6], 17);
B = C + lrot(B + 0xFD469501 + R1(C, D, A) + block[7], 22);
A = B + lrot(A + 0x698098D8 + R1(B, C, D) + block[8], 7);
D = A + lrot(D + 0x8B44F7AF + R1(A, B, C) + block[9], 12);
C = D + lrot(C + 0xFFFF5BB1 + R1(D, A, B) + block[10], 17);
B = C + lrot(B + 0x895CD7BE + R1(C, D, A) + block[11], 22);
A = B + lrot(A + 0x6B901122 + R1(B, C, D) + block[12], 7);
D = A + lrot(D + 0xFD987193 + R1(A, B, C) + block[13], 12);
C = D + lrot(C + 0xA679438E + R1(D, A, B) + block[14], 17);
B = C + lrot(B + 0x49B40821 + R1(C, D, A) + block[15], 22);
#define R2(N, O, P) ((P & N) | (~P & O))
A = B + lrot(A + 0xF61E2562 + R2(B, C, D) + block[1], 5);
D = A + lrot(D + 0xC040B340 + R2(A, B, C) + block[6], 9);
C = D + lrot(C + 0x265E5A51 + R2(D, A, B) + block[11], 14);
B = C + lrot(B + 0xE9B6C7AA + R2(C, D, A) + block[0], 20);
A = B + lrot(A + 0xD62F105D + R2(B, C, D) + block[5], 5);
D = A + lrot(D + 0x02441453 + R2(A, B, C) + block[10], 9);
C = D + lrot(C + 0xD8A1E681 + R2(D, A, B) + block[15], 14);
B = C + lrot(B + 0xE7D3FBC8 + R2(C, D, A) + block[4], 20);
A = B + lrot(A + 0x21E1CDE6 + R2(B, C, D) + block[9], 5);
D = A + lrot(D + 0xC33707D6 + R2(A, B, C) + block[14], 9);
C = D + lrot(C + 0xF4D50D87 + R2(D, A, B) + block[3], 14);
B = C + lrot(B + 0x455A14ED + R2(C, D, A) + block[8], 20);
A = B + lrot(A + 0xA9E3E905 + R2(B, C, D) + block[13], 5);
D = A + lrot(D + 0xFCEFA3F8 + R2(A, B, C) + block[2], 9);
C = D + lrot(C + 0x676F02D9 + R2(D, A, B) + block[7], 14);
B = C + lrot(B + 0x8D2A4C8A + R2(C, D, A) + block[12], 20);
#define R3(N, O, P) (N ^ O ^ P)
A = B + lrot(A + 0xFFFA3942 + R3(B, C, D) + block[5], 4);
D = A + lrot(D + 0x8771F681 + R3(A, B, C) + block[8], 11);
C = D + lrot(C + 0x6D9D6122 + R3(D, A, B) + block[11], 16);
B = C + lrot(B + 0xFDE5380C + R3(C, D, A) + block[14], 23);
A = B + lrot(A + 0xA4BEEA44 + R3(B, C, D) + block[1], 4);
D = A + lrot(D + 0x4BDECFA9 + R3(A, B, C) + block[4], 11);
C = D + lrot(C + 0xF6BB4B60 + R3(D, A, B) + block[7], 16);
B = C + lrot(B + 0xBEBFBC70 + R3(C, D, A) + block[10], 23);
A = B + lrot(A + 0x289B7EC6 + R3(B, C, D) + block[13], 4);
D = A + lrot(D + 0xEAA127FA + R3(A, B, C) + block[0], 11);
C = D + lrot(C + 0xD4EF3085 + R3(D, A, B) + block[3], 16);
B = C + lrot(B + 0x04881D05 + R3(C, D, A) + block[6], 23);
A = B + lrot(A + 0xD9D4D039 + R3(B, C, D) + block[9], 4);
D = A + lrot(D + 0xE6DB99E5 + R3(A, B, C) + block[12], 11);
C = D + lrot(C + 0x1FA27CF8 + R3(D, A, B) + block[15], 16);
B = C + lrot(B + 0xC4AC5665 + R3(C, D, A) + block[2], 23);
#define R4(N, O, P) (O ^ (N | ~P))
A = B + lrot(A + 0xF4292244 + R4(B, C, D) + block[0], 6);
D = A + lrot(D + 0x432AFF97 + R4(A, B, C) + block[7], 10);
C = D + lrot(C + 0xAB9423A7 + R4(D, A, B) + block[14], 15);
B = C + lrot(B + 0xFC93A039 + R4(C, D, A) + block[5], 21);
A = B + lrot(A + 0x655B59C3 + R4(B, C, D) + block[12], 6);
D = A + lrot(D + 0x8F0CCC92 + R4(A, B, C) + block[3], 10);
C = D + lrot(C + 0xFFEFF47D + R4(D, A, B) + block[10], 15);
B = C + lrot(B + 0x85845DD1 + R4(C, D, A) + block[1], 21);
A = B + lrot(A + 0x6FA87E4F + R4(B, C, D) + block[8], 6);
D = A + lrot(D + 0xFE2CE6E0 + R4(A, B, C) + block[15], 10);
C = D + lrot(C + 0xA3014314 + R4(D, A, B) + block[6], 15);
B = C + lrot(B + 0x4E0811A1 + R4(C, D, A) + block[13], 21);
A = B + lrot(A + 0xF7537E82 + R4(B, C, D) + block[4], 6);
D = A + lrot(D + 0xBD3AF235 + R4(A, B, C) + block[11], 10);
C = D + lrot(C + 0x2AD7D2BB + R4(D, A, B) + block[2], 15);
B = C + lrot(B + 0xEB86D391 + R4(C, D, A) + block[9], 21);
*A0 += A;
*B0 += B;
*C0 += C;
*D0 += D;
}
void md5(char *digest, const char *input, size_t length)
{
size_t blocksize = length + 0x48 & ~0x3F;
char *block = malloc(blocksize);
memset(block, 0, blocksize);
memcpy(block, input, length);
block[length] = 0x80;
((unsigned int *)(block + blocksize))[-2] = length << 3;
((unsigned int *)(block + blocksize))[-1] = length >> 29;
unsigned int A0 = 0x67452301;
unsigned int B0 = 0xEFCDAB89;
unsigned int C0 = 0x98BADCFE;
unsigned int D0 = 0x10325476;
int i;
for(i = 0; i < blocksize; i += 0x40)
block_round(&A0, &B0, &C0, &D0, (unsigned int *)(block + i));
free(block);
((unsigned int *)digest)[0] = A0;
((unsigned int *)digest)[1] = B0;
((unsigned int *)digest)[2] = C0;
((unsigned int *)digest)[3] = D0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment