/* * Copyright (C) 2016 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o. * * This file is part of MooseFS. * * MooseFS 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, version 2 (only). * * MooseFS 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 MooseFS; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA * or visit http://www.gnu.org/licenses/gpl-2.0.html */ #include #include #include "md5.h" #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 static const uint8_t padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #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))) #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } static void md5_encode (uint8_t *output,const uint32_t *input,uint32_t len) { uint32_t i,j; for (i=0,j=0 ; i>8)&0xff); output[j+2] = (uint8_t)((input[i]>>16)&0xff); output[j+3] = (uint8_t)((input[i]>>24)&0xff); } } static void md5_decode (uint32_t *output,const uint8_t *input,uint32_t len) { uint32_t i,j; for (i=0,j=0 ; icount[0] = ctx->count[1] = 0; ctx->state[0] = 0x67452301U; ctx->state[1] = 0xefcdab89U; ctx->state[2] = 0x98badcfeU; ctx->state[3] = 0x10325476U; } void md5_update (md5ctx *ctx,const uint8_t *buff,uint32_t leng) { uint32_t i,indx,partleng; indx = (uint32_t)((ctx->count[0]>>3)&0x3F); if ((ctx->count[0]+=((uint32_t)leng<<3)) < ((uint32_t)leng<<3)) { ctx->count[1]++; } ctx->count[1] += ((uint32_t)leng>>29); partleng = 64-indx; if (leng>=partleng) { memcpy((char*)(ctx->buffer+indx),(const char*)buff,partleng); md5_transform(ctx->state,ctx->buffer); for (i=partleng ; i+63state,buff+i); } indx = 0; } else { i = 0; } memcpy((char*)(ctx->buffer+indx),(const char*)(buff+i),leng-i); } void md5_final (uint8_t digest[16],md5ctx *ctx) { uint8_t bits[8]; uint32_t indx,padleng; md5_encode(bits,ctx->count,2); indx = (uint32_t)((ctx->count[0]>>3)&0x3f); padleng = (indx<56)?(56-indx):(120-indx); md5_update (ctx,padding,padleng); md5_update(ctx,bits,8); md5_encode(digest,ctx->state,4); memset((char*)ctx,0,sizeof(md5ctx)); }