Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_md5.cpp
35267 views
//===-- tsan_md5.cpp ------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of ThreadSanitizer (TSan), a race detector.9//10//===----------------------------------------------------------------------===//11#include "tsan_defs.h"1213namespace __tsan {1415#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))16#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))17#define H(x, y, z) ((x) ^ (y) ^ (z))18#define I(x, y, z) ((y) ^ ((x) | ~(z)))1920#define STEP(f, a, b, c, d, x, t, s) \21(a) += f((b), (c), (d)) + (x) + (t); \22(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \23(a) += (b);2425#define SET(n) \26(*(const MD5_u32plus *)&ptr[(n) * 4])27#define GET(n) \28SET(n)2930typedef unsigned int MD5_u32plus;31typedef unsigned long ulong_t;3233typedef struct {34MD5_u32plus lo, hi;35MD5_u32plus a, b, c, d;36unsigned char buffer[64];37MD5_u32plus block[16];38} MD5_CTX;3940static const void *body(MD5_CTX *ctx, const void *data, ulong_t size) {41const unsigned char *ptr = (const unsigned char *)data;42MD5_u32plus a, b, c, d;43MD5_u32plus saved_a, saved_b, saved_c, saved_d;4445a = ctx->a;46b = ctx->b;47c = ctx->c;48d = ctx->d;4950do {51saved_a = a;52saved_b = b;53saved_c = c;54saved_d = d;5556STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)57STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)58STEP(F, c, d, a, b, SET(2), 0x242070db, 17)59STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)60STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)61STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)62STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)63STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)64STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)65STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)66STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)67STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)68STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)69STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)70STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)71STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)7273STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)74STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)75STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)76STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)77STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)78STEP(G, d, a, b, c, GET(10), 0x02441453, 9)79STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)80STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)81STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)82STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)83STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)84STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)85STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)86STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)87STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)88STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)8990STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)91STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)92STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)93STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)94STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)95STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)96STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)97STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)98STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)99STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)100STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)101STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)102STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)103STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)104STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)105STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)106107STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)108STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)109STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)110STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)111STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)112STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)113STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)114STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)115STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)116STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)117STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)118STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)119STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)120STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)121STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)122STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)123124a += saved_a;125b += saved_b;126c += saved_c;127d += saved_d;128129ptr += 64;130} while (size -= 64);131132ctx->a = a;133ctx->b = b;134ctx->c = c;135ctx->d = d;136137return ptr;138}139140#undef F141#undef G142#undef H143#undef I144#undef STEP145#undef SET146#undef GET147148void MD5_Init(MD5_CTX *ctx) {149ctx->a = 0x67452301;150ctx->b = 0xefcdab89;151ctx->c = 0x98badcfe;152ctx->d = 0x10325476;153154ctx->lo = 0;155ctx->hi = 0;156}157158void MD5_Update(MD5_CTX *ctx, const void *data, ulong_t size) {159MD5_u32plus saved_lo;160ulong_t used, free;161162saved_lo = ctx->lo;163if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)164ctx->hi++;165ctx->hi += size >> 29;166167used = saved_lo & 0x3f;168169if (used) {170free = 64 - used;171172if (size < free) {173internal_memcpy(&ctx->buffer[used], data, size);174return;175}176177internal_memcpy(&ctx->buffer[used], data, free);178data = (const unsigned char *)data + free;179size -= free;180body(ctx, ctx->buffer, 64);181}182183if (size >= 64) {184data = body(ctx, data, size & ~(ulong_t)0x3f);185size &= 0x3f;186}187188internal_memcpy(ctx->buffer, data, size);189}190191void MD5_Final(unsigned char *result, MD5_CTX *ctx) {192ulong_t used, free;193194used = ctx->lo & 0x3f;195196ctx->buffer[used++] = 0x80;197198free = 64 - used;199200if (free < 8) {201internal_memset(&ctx->buffer[used], 0, free);202body(ctx, ctx->buffer, 64);203used = 0;204free = 64;205}206207internal_memset(&ctx->buffer[used], 0, free - 8);208209ctx->lo <<= 3;210ctx->buffer[56] = ctx->lo;211ctx->buffer[57] = ctx->lo >> 8;212ctx->buffer[58] = ctx->lo >> 16;213ctx->buffer[59] = ctx->lo >> 24;214ctx->buffer[60] = ctx->hi;215ctx->buffer[61] = ctx->hi >> 8;216ctx->buffer[62] = ctx->hi >> 16;217ctx->buffer[63] = ctx->hi >> 24;218219body(ctx, ctx->buffer, 64);220221result[0] = ctx->a;222result[1] = ctx->a >> 8;223result[2] = ctx->a >> 16;224result[3] = ctx->a >> 24;225result[4] = ctx->b;226result[5] = ctx->b >> 8;227result[6] = ctx->b >> 16;228result[7] = ctx->b >> 24;229result[8] = ctx->c;230result[9] = ctx->c >> 8;231result[10] = ctx->c >> 16;232result[11] = ctx->c >> 24;233result[12] = ctx->d;234result[13] = ctx->d >> 8;235result[14] = ctx->d >> 16;236result[15] = ctx->d >> 24;237238internal_memset(ctx, 0, sizeof(*ctx));239}240241MD5Hash md5_hash(const void *data, uptr size) {242MD5Hash res;243MD5_CTX ctx;244MD5_Init(&ctx);245MD5_Update(&ctx, data, size);246MD5_Final((unsigned char*)&res.hash[0], &ctx);247return res;248}249} // namespace __tsan250251252