00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "config.h"
00038
00039 #include <isc/assertions.h>
00040 #include <isc/md5.h>
00041 #include <isc/platform.h>
00042 #include <isc/string.h>
00043 #include <isc/types.h>
00044
00045 #if PKCS11CRYPTO
00046 #include <pk11/internal.h>
00047 #include <pk11/pk11.h>
00048 #endif
00049
00050 #include <isc/util.h>
00051
00052 #ifdef ISC_PLATFORM_OPENSSLHASH
00053 void
00054 isc_md5_init(isc_md5_t *ctx) {
00055 RUNTIME_CHECK(EVP_DigestInit(ctx, EVP_md5()) == 1);
00056 }
00057
00058 void
00059 isc_md5_invalidate(isc_md5_t *ctx) {
00060 EVP_MD_CTX_cleanup(ctx);
00061 }
00062
00063 void
00064 isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
00065 RUNTIME_CHECK(EVP_DigestUpdate(ctx,
00066 (const void *) buf,
00067 (size_t) len) == 1);
00068 }
00069
00070 void
00071 isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
00072 RUNTIME_CHECK(EVP_DigestFinal(ctx, digest, NULL) == 1);
00073 }
00074
00075 #elif PKCS11CRYPTO
00076
00077 void
00078 isc_md5_init(isc_md5_t *ctx) {
00079 CK_RV rv;
00080 CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
00081
00082 RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00083 ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00084 PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
00085 }
00086
00087 void
00088 isc_md5_invalidate(isc_md5_t *ctx) {
00089 CK_BYTE garbage[ISC_MD5_DIGESTLENGTH];
00090 CK_ULONG len = ISC_MD5_DIGESTLENGTH;
00091
00092 if (ctx->handle == NULL)
00093 return;
00094 (void) pkcs_C_DigestFinal(ctx->session, garbage, &len);
00095 memset(garbage, 0, sizeof(garbage));
00096 pk11_return_session(ctx);
00097 }
00098
00099 void
00100 isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
00101 CK_RV rv;
00102 CK_BYTE_PTR pPart;
00103
00104 DE_CONST(buf, pPart);
00105 PK11_FATALCHECK(pkcs_C_DigestUpdate,
00106 (ctx->session, pPart, (CK_ULONG) len));
00107 }
00108
00109 void
00110 isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
00111 CK_RV rv;
00112 CK_ULONG len = ISC_MD5_DIGESTLENGTH;
00113
00114 PK11_FATALCHECK(pkcs_C_DigestFinal,
00115 (ctx->session, (CK_BYTE_PTR) digest, &len));
00116 pk11_return_session(ctx);
00117 }
00118
00119 #else
00120
00121 static void
00122 byteSwap(isc_uint32_t *buf, unsigned words)
00123 {
00124 unsigned char *p = (unsigned char *)buf;
00125
00126 do {
00127 *buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 |
00128 ((unsigned)p[1] << 8 | p[0]);
00129 p += 4;
00130 } while (--words);
00131 }
00132
00133
00134
00135
00136
00137 void
00138 isc_md5_init(isc_md5_t *ctx) {
00139 ctx->buf[0] = 0x67452301;
00140 ctx->buf[1] = 0xefcdab89;
00141 ctx->buf[2] = 0x98badcfe;
00142 ctx->buf[3] = 0x10325476;
00143
00144 ctx->bytes[0] = 0;
00145 ctx->bytes[1] = 0;
00146 }
00147
00148 void
00149 isc_md5_invalidate(isc_md5_t *ctx) {
00150 memset(ctx, 0, sizeof(isc_md5_t));
00151 }
00152
00153
00154
00155
00156
00157 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00158 #define F2(x, y, z) F1(z, x, y)
00159 #define F3(x, y, z) (x ^ y ^ z)
00160 #define F4(x, y, z) (y ^ (x | ~z))
00161
00162
00163
00164 #define MD5STEP(f,w,x,y,z,in,s) \
00165 (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
00166
00167
00168
00169
00170
00171
00172 static void
00173 transform(isc_uint32_t buf[4], isc_uint32_t const in[16]) {
00174 register isc_uint32_t a, b, c, d;
00175
00176 a = buf[0];
00177 b = buf[1];
00178 c = buf[2];
00179 d = buf[3];
00180
00181 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
00182 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
00183 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
00184 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
00185 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
00186 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
00187 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
00188 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
00189 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
00190 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
00191 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
00192 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
00193 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
00194 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
00195 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
00196 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
00197
00198 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
00199 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
00200 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
00201 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
00202 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
00203 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
00204 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
00205 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
00206 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
00207 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
00208 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
00209 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
00210 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
00211 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
00212 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
00213 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
00214
00215 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
00216 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
00217 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
00218 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
00219 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
00220 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
00221 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
00222 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
00223 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
00224 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
00225 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
00226 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
00227 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
00228 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
00229 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
00230 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
00231
00232 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
00233 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
00234 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
00235 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
00236 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
00237 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
00238 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
00239 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
00240 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
00241 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
00242 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
00243 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
00244 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
00245 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
00246 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
00247 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
00248
00249 buf[0] += a;
00250 buf[1] += b;
00251 buf[2] += c;
00252 buf[3] += d;
00253 }
00254
00255
00256
00257
00258
00259 void
00260 isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
00261 isc_uint32_t t;
00262
00263
00264
00265 t = ctx->bytes[0];
00266 if ((ctx->bytes[0] = t + len) < t)
00267 ctx->bytes[1]++;
00268
00269 t = 64 - (t & 0x3f);
00270 if (t > len) {
00271 memmove((unsigned char *)ctx->in + 64 - t, buf, len);
00272 return;
00273 }
00274
00275 memmove((unsigned char *)ctx->in + 64 - t, buf, t);
00276 byteSwap(ctx->in, 16);
00277 transform(ctx->buf, ctx->in);
00278 buf += t;
00279 len -= t;
00280
00281
00282 while (len >= 64) {
00283 memmove(ctx->in, buf, 64);
00284 byteSwap(ctx->in, 16);
00285 transform(ctx->buf, ctx->in);
00286 buf += 64;
00287 len -= 64;
00288 }
00289
00290
00291 memmove(ctx->in, buf, len);
00292 }
00293
00294
00295
00296
00297
00298 void
00299 isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
00300 int count = ctx->bytes[0] & 0x3f;
00301 unsigned char *p = (unsigned char *)ctx->in + count;
00302
00303
00304 *p++ = 0x80;
00305
00306
00307 count = 56 - 1 - count;
00308
00309 if (count < 0) {
00310 memset(p, 0, count + 8);
00311 byteSwap(ctx->in, 16);
00312 transform(ctx->buf, ctx->in);
00313 p = (unsigned char *)ctx->in;
00314 count = 56;
00315 }
00316 memset(p, 0, count);
00317 byteSwap(ctx->in, 14);
00318
00319
00320 ctx->in[14] = ctx->bytes[0] << 3;
00321 ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
00322 transform(ctx->buf, ctx->in);
00323
00324 byteSwap(ctx->buf, 4);
00325 memmove(digest, ctx->buf, 16);
00326 memset(ctx, 0, sizeof(isc_md5_t));
00327 }
00328 #endif