1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2023 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2023 The SQLite Project. 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci *//*! 21e5c31af7Sopenharmony_ci * \file 22e5c31af7Sopenharmony_ci * \brief Utilities for calculating MD5 checksums. 23e5c31af7Sopenharmony_ci * 24e5c31af7Sopenharmony_ci * This file was modified from Chromium, 25e5c31af7Sopenharmony_ci * https://chromium.googlesource.com/chromium/src/base/+/7ef85b701132474f71e6369f081a2fb84582ee88/md5.cc 26e5c31af7Sopenharmony_ci * 27e5c31af7Sopenharmony_ci * This code implements the MD5 message-digest algorithm. 28e5c31af7Sopenharmony_ci * The algorithm is due to Ron Rivest. This code was 29e5c31af7Sopenharmony_ci * written by Colin Plumb in 1993, no copyright is claimed. 30e5c31af7Sopenharmony_ci * This code is in the public domain; do with it what you wish. 31e5c31af7Sopenharmony_ci * 32e5c31af7Sopenharmony_ci * Equivalent code is available from RSA Data Security, Inc. 33e5c31af7Sopenharmony_ci * This code has been tested against that, and is equivalent, 34e5c31af7Sopenharmony_ci * except that you don't need to include two pages of legalese 35e5c31af7Sopenharmony_ci * with every copy. 36e5c31af7Sopenharmony_ci * 37e5c31af7Sopenharmony_ci * To compute the message digest of a chunk of bytes, declare an 38e5c31af7Sopenharmony_ci * MD5Context structure, pass it to MD5Init, call MD5Update as 39e5c31af7Sopenharmony_ci * needed on buffers full of bytes, and then call MD5Final, which 40e5c31af7Sopenharmony_ci * will fill a supplied 16-byte array with the digest. 41e5c31af7Sopenharmony_ci * --------------------------------------------------------------------*/ 42e5c31af7Sopenharmony_ci#include "vkMd5Sum.hpp" 43e5c31af7Sopenharmony_ci#include <deMemory.h> 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_cinamespace vk 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_cistruct Context 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_ci deUint32 buf[4]; 51e5c31af7Sopenharmony_ci deUint32 bits[2]; 52e5c31af7Sopenharmony_ci deUint8 in[64]; 53e5c31af7Sopenharmony_ci}; 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ci/* 56e5c31af7Sopenharmony_ci * Note: this code is harmless on little-endian machines. 57e5c31af7Sopenharmony_ci */ 58e5c31af7Sopenharmony_civoid byteReverse(deUint8* buf, unsigned longs) 59e5c31af7Sopenharmony_ci{ 60e5c31af7Sopenharmony_ci deUint32 t; 61e5c31af7Sopenharmony_ci do 62e5c31af7Sopenharmony_ci { 63e5c31af7Sopenharmony_ci t = (deUint32)((unsigned)buf[3] << 8 | buf[2]) << 16 | ((unsigned)buf[1] << 8 | buf[0]); 64e5c31af7Sopenharmony_ci *(deUint32*)buf = t; 65e5c31af7Sopenharmony_ci buf += 4; 66e5c31af7Sopenharmony_ci } 67e5c31af7Sopenharmony_ci while (--longs); 68e5c31af7Sopenharmony_ci} 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci/* The four core functions - F1 is optimized somewhat */ 71e5c31af7Sopenharmony_ci/* #define F1(x, y, z) (x & y | ~x & z) */ 72e5c31af7Sopenharmony_ci#define F1(x, y, z) (z ^ (x & (y ^ z))) 73e5c31af7Sopenharmony_ci#define F2(x, y, z) F1(z, x, y) 74e5c31af7Sopenharmony_ci#define F3(x, y, z) (x ^ y ^ z) 75e5c31af7Sopenharmony_ci#define F4(x, y, z) (y ^ (x | ~z)) 76e5c31af7Sopenharmony_ci/* This is the central step in the MD5 algorithm. */ 77e5c31af7Sopenharmony_ci#define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) 78e5c31af7Sopenharmony_ci/* 79e5c31af7Sopenharmony_ci * The core of the MD5 algorithm, this alters an existing MD5 hash to 80e5c31af7Sopenharmony_ci * reflect the addition of 16 longwords of new data. MD5Update blocks 81e5c31af7Sopenharmony_ci * the data and converts bytes into longwords for this routine. 82e5c31af7Sopenharmony_ci */ 83e5c31af7Sopenharmony_civoid MD5Transform(deUint32 buf[4], const deUint32 in[16]) 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_ci deUint32 a, b, c, d; 86e5c31af7Sopenharmony_ci a = buf[0]; 87e5c31af7Sopenharmony_ci b = buf[1]; 88e5c31af7Sopenharmony_ci c = buf[2]; 89e5c31af7Sopenharmony_ci d = buf[3]; 90e5c31af7Sopenharmony_ci MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 91e5c31af7Sopenharmony_ci MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 92e5c31af7Sopenharmony_ci MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 93e5c31af7Sopenharmony_ci MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 94e5c31af7Sopenharmony_ci MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 95e5c31af7Sopenharmony_ci MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 96e5c31af7Sopenharmony_ci MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 97e5c31af7Sopenharmony_ci MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 98e5c31af7Sopenharmony_ci MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 99e5c31af7Sopenharmony_ci MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 100e5c31af7Sopenharmony_ci MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 101e5c31af7Sopenharmony_ci MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 102e5c31af7Sopenharmony_ci MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 103e5c31af7Sopenharmony_ci MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 104e5c31af7Sopenharmony_ci MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 105e5c31af7Sopenharmony_ci MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 106e5c31af7Sopenharmony_ci MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 107e5c31af7Sopenharmony_ci MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 108e5c31af7Sopenharmony_ci MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 109e5c31af7Sopenharmony_ci MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 110e5c31af7Sopenharmony_ci MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 111e5c31af7Sopenharmony_ci MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 112e5c31af7Sopenharmony_ci MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 113e5c31af7Sopenharmony_ci MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 114e5c31af7Sopenharmony_ci MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 115e5c31af7Sopenharmony_ci MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 116e5c31af7Sopenharmony_ci MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 117e5c31af7Sopenharmony_ci MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 118e5c31af7Sopenharmony_ci MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 119e5c31af7Sopenharmony_ci MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 120e5c31af7Sopenharmony_ci MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 121e5c31af7Sopenharmony_ci MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 122e5c31af7Sopenharmony_ci MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 123e5c31af7Sopenharmony_ci MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 124e5c31af7Sopenharmony_ci MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 125e5c31af7Sopenharmony_ci MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 126e5c31af7Sopenharmony_ci MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 127e5c31af7Sopenharmony_ci MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 128e5c31af7Sopenharmony_ci MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 129e5c31af7Sopenharmony_ci MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 130e5c31af7Sopenharmony_ci MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 131e5c31af7Sopenharmony_ci MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 132e5c31af7Sopenharmony_ci MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 133e5c31af7Sopenharmony_ci MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 134e5c31af7Sopenharmony_ci MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 135e5c31af7Sopenharmony_ci MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 136e5c31af7Sopenharmony_ci MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 137e5c31af7Sopenharmony_ci MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 138e5c31af7Sopenharmony_ci MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 139e5c31af7Sopenharmony_ci MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 140e5c31af7Sopenharmony_ci MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 141e5c31af7Sopenharmony_ci MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 142e5c31af7Sopenharmony_ci MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 143e5c31af7Sopenharmony_ci MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 144e5c31af7Sopenharmony_ci MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 145e5c31af7Sopenharmony_ci MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 146e5c31af7Sopenharmony_ci MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 147e5c31af7Sopenharmony_ci MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 148e5c31af7Sopenharmony_ci MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 149e5c31af7Sopenharmony_ci MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 150e5c31af7Sopenharmony_ci MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 151e5c31af7Sopenharmony_ci MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 152e5c31af7Sopenharmony_ci MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 153e5c31af7Sopenharmony_ci MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 154e5c31af7Sopenharmony_ci buf[0] += a; 155e5c31af7Sopenharmony_ci buf[1] += b; 156e5c31af7Sopenharmony_ci buf[2] += c; 157e5c31af7Sopenharmony_ci buf[3] += d; 158e5c31af7Sopenharmony_ci} 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci/* 161e5c31af7Sopenharmony_ci * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 162e5c31af7Sopenharmony_ci * initialization constants. 163e5c31af7Sopenharmony_ci */ 164e5c31af7Sopenharmony_civoid MD5Init(MD5Context* context) 165e5c31af7Sopenharmony_ci{ 166e5c31af7Sopenharmony_ci struct Context* ctx = (struct Context*)context; 167e5c31af7Sopenharmony_ci ctx->buf[0] = 0x67452301; 168e5c31af7Sopenharmony_ci ctx->buf[1] = 0xefcdab89; 169e5c31af7Sopenharmony_ci ctx->buf[2] = 0x98badcfe; 170e5c31af7Sopenharmony_ci ctx->buf[3] = 0x10325476; 171e5c31af7Sopenharmony_ci ctx->bits[0] = 0; 172e5c31af7Sopenharmony_ci ctx->bits[1] = 0; 173e5c31af7Sopenharmony_ci} 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci/* 176e5c31af7Sopenharmony_ci * Update context to reflect the concatenation of another buffer full 177e5c31af7Sopenharmony_ci * of bytes. 178e5c31af7Sopenharmony_ci */ 179e5c31af7Sopenharmony_civoid MD5Update(MD5Context* context, const deUint8* data, std::size_t len) 180e5c31af7Sopenharmony_ci{ 181e5c31af7Sopenharmony_ci const deUint8* inbuf = data; 182e5c31af7Sopenharmony_ci struct Context* ctx = (struct Context*)context; 183e5c31af7Sopenharmony_ci const deUint8* buf = (const deUint8*)inbuf; 184e5c31af7Sopenharmony_ci deUint32 t; 185e5c31af7Sopenharmony_ci /* Update bitcount */ 186e5c31af7Sopenharmony_ci t = ctx->bits[0]; 187e5c31af7Sopenharmony_ci if ((ctx->bits[0] = t + ((deUint32)len << 3)) < t) 188e5c31af7Sopenharmony_ci ctx->bits[1]++; /* Carry from low to high */ 189e5c31af7Sopenharmony_ci ctx->bits[1] += static_cast<deUint32>(len >> 29); 190e5c31af7Sopenharmony_ci t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 191e5c31af7Sopenharmony_ci /* Handle any leading odd-sized chunks */ 192e5c31af7Sopenharmony_ci if (t) 193e5c31af7Sopenharmony_ci { 194e5c31af7Sopenharmony_ci deUint8* p = (deUint8*)ctx->in + t; 195e5c31af7Sopenharmony_ci t = 64 - t; 196e5c31af7Sopenharmony_ci if (len < t) 197e5c31af7Sopenharmony_ci { 198e5c31af7Sopenharmony_ci deMemcpy(p, buf, len); 199e5c31af7Sopenharmony_ci return; 200e5c31af7Sopenharmony_ci } 201e5c31af7Sopenharmony_ci deMemcpy(p, buf, t); 202e5c31af7Sopenharmony_ci byteReverse(ctx->in, 16); 203e5c31af7Sopenharmony_ci MD5Transform(ctx->buf, (deUint32*)ctx->in); 204e5c31af7Sopenharmony_ci buf += t; 205e5c31af7Sopenharmony_ci len -= t; 206e5c31af7Sopenharmony_ci } 207e5c31af7Sopenharmony_ci /* Process data in 64-byte chunks */ 208e5c31af7Sopenharmony_ci while (len >= 64) 209e5c31af7Sopenharmony_ci { 210e5c31af7Sopenharmony_ci deMemcpy(ctx->in, buf, 64); 211e5c31af7Sopenharmony_ci byteReverse(ctx->in, 16); 212e5c31af7Sopenharmony_ci MD5Transform(ctx->buf, (deUint32*)ctx->in); 213e5c31af7Sopenharmony_ci buf += 64; 214e5c31af7Sopenharmony_ci len -= 64; 215e5c31af7Sopenharmony_ci } 216e5c31af7Sopenharmony_ci /* Handle any remaining bytes of data. */ 217e5c31af7Sopenharmony_ci deMemcpy(ctx->in, buf, len); 218e5c31af7Sopenharmony_ci} 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci/* 221e5c31af7Sopenharmony_ci * Final wrapup - pad to 64-byte boundary with the bit pattern 222e5c31af7Sopenharmony_ci * 1 0* (64-bit count of bits processed, MSB-first) 223e5c31af7Sopenharmony_ci */ 224e5c31af7Sopenharmony_civoid MD5Final(MD5Digest* digest, MD5Context* context) 225e5c31af7Sopenharmony_ci{ 226e5c31af7Sopenharmony_ci struct Context* ctx = (struct Context*)context; 227e5c31af7Sopenharmony_ci unsigned count; 228e5c31af7Sopenharmony_ci deUint8* p; 229e5c31af7Sopenharmony_ci /* Compute number of bytes mod 64 */ 230e5c31af7Sopenharmony_ci count = (ctx->bits[0] >> 3) & 0x3F; 231e5c31af7Sopenharmony_ci /* Set the first char of padding to 0x80. This is safe since there is 232e5c31af7Sopenharmony_ci always at least one byte free */ 233e5c31af7Sopenharmony_ci p = ctx->in + count; 234e5c31af7Sopenharmony_ci *p++ = 0x80; 235e5c31af7Sopenharmony_ci /* Bytes of padding needed to make 64 bytes */ 236e5c31af7Sopenharmony_ci count = 64 - 1 - count; 237e5c31af7Sopenharmony_ci /* Pad out to 56 mod 64 */ 238e5c31af7Sopenharmony_ci if (count < 8) 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci /* Two lots of padding: Pad the first block to 64 bytes */ 241e5c31af7Sopenharmony_ci deMemset(p, 0, count); 242e5c31af7Sopenharmony_ci byteReverse(ctx->in, 16); 243e5c31af7Sopenharmony_ci MD5Transform(ctx->buf, (deUint32*)ctx->in); 244e5c31af7Sopenharmony_ci /* Now fill the next block with 56 bytes */ 245e5c31af7Sopenharmony_ci deMemset(ctx->in, 0, 56); 246e5c31af7Sopenharmony_ci } 247e5c31af7Sopenharmony_ci else 248e5c31af7Sopenharmony_ci { 249e5c31af7Sopenharmony_ci /* Pad block to 56 bytes */ 250e5c31af7Sopenharmony_ci deMemset(p, 0, count - 8); 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci byteReverse(ctx->in, 14); 253e5c31af7Sopenharmony_ci /* Append length in bits and transform */ 254e5c31af7Sopenharmony_ci ((deUint32*)ctx->in)[14] = ctx->bits[0]; 255e5c31af7Sopenharmony_ci ((deUint32*)ctx->in)[15] = ctx->bits[1]; 256e5c31af7Sopenharmony_ci MD5Transform(ctx->buf, (deUint32*)ctx->in); 257e5c31af7Sopenharmony_ci byteReverse((deUint8*)ctx->buf, 4); 258e5c31af7Sopenharmony_ci deMemcpy(digest->a, ctx->buf, 16); 259e5c31af7Sopenharmony_ci deMemset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ 260e5c31af7Sopenharmony_ci} 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_cistd::string MD5DigestToBase16(const MD5Digest& digest) 263e5c31af7Sopenharmony_ci{ 264e5c31af7Sopenharmony_ci static char const zEncode[] = "0123456789abcdef"; 265e5c31af7Sopenharmony_ci std::string ret; 266e5c31af7Sopenharmony_ci ret.resize(32); 267e5c31af7Sopenharmony_ci int j = 0; 268e5c31af7Sopenharmony_ci for (int i = 0; i < 16; i++) 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci int a = digest.a[i]; 271e5c31af7Sopenharmony_ci ret[j++] = zEncode[(a >> 4) & 0xf]; 272e5c31af7Sopenharmony_ci ret[j++] = zEncode[a & 0xf]; 273e5c31af7Sopenharmony_ci } 274e5c31af7Sopenharmony_ci return ret; 275e5c31af7Sopenharmony_ci} 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_civoid MD5Sum(const void* data, std::size_t length, MD5Digest* digest) 278e5c31af7Sopenharmony_ci{ 279e5c31af7Sopenharmony_ci MD5Context ctx; 280e5c31af7Sopenharmony_ci MD5Init(&ctx); 281e5c31af7Sopenharmony_ci MD5Update(&ctx, reinterpret_cast<const deUint8*>(data), length); 282e5c31af7Sopenharmony_ci MD5Final(digest, &ctx); 283e5c31af7Sopenharmony_ci} 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_cistd::string MD5SumBase16(const void* data, std::size_t length) 286e5c31af7Sopenharmony_ci{ 287e5c31af7Sopenharmony_ci MD5Digest digest; 288e5c31af7Sopenharmony_ci MD5Sum(data, length, &digest); 289e5c31af7Sopenharmony_ci return MD5DigestToBase16(digest); 290e5c31af7Sopenharmony_ci} 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci} // namespace vkt 293