1*00b67f09SDavid van Moolenbroek /* $NetBSD: hmacmd5.c,v 1.8 2015/07/08 17:28:59 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004-2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 2000, 2001 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id: hmacmd5.c,v 1.16 2009/02/06 23:47:42 tbox Exp */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*! \file
23*00b67f09SDavid van Moolenbroek * This code implements the HMAC-MD5 keyed hash algorithm
24*00b67f09SDavid van Moolenbroek * described in RFC2104.
25*00b67f09SDavid van Moolenbroek */
26*00b67f09SDavid van Moolenbroek
27*00b67f09SDavid van Moolenbroek #include "config.h"
28*00b67f09SDavid van Moolenbroek
29*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
30*00b67f09SDavid van Moolenbroek #include <isc/hmacmd5.h>
31*00b67f09SDavid van Moolenbroek #include <isc/md5.h>
32*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
33*00b67f09SDavid van Moolenbroek #include <isc/safe.h>
34*00b67f09SDavid van Moolenbroek #include <isc/string.h>
35*00b67f09SDavid van Moolenbroek #include <isc/types.h>
36*00b67f09SDavid van Moolenbroek #include <isc/util.h>
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek #if PKCS11CRYPTO || PKCS11CRYPTOWITHHMAC
39*00b67f09SDavid van Moolenbroek #include <pk11/internal.h>
40*00b67f09SDavid van Moolenbroek #include <pk11/pk11.h>
41*00b67f09SDavid van Moolenbroek #endif
42*00b67f09SDavid van Moolenbroek
43*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_OPENSSLHASH
44*00b67f09SDavid van Moolenbroek
45*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_init(isc_hmacmd5_t * ctx,const unsigned char * key,unsigned int len)46*00b67f09SDavid van Moolenbroek isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
47*00b67f09SDavid van Moolenbroek unsigned int len)
48*00b67f09SDavid van Moolenbroek {
49*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
50*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
51*00b67f09SDavid van Moolenbroek (int) len, EVP_md5()) == 1);
52*00b67f09SDavid van Moolenbroek #else
53*00b67f09SDavid van Moolenbroek HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5());
54*00b67f09SDavid van Moolenbroek #endif
55*00b67f09SDavid van Moolenbroek }
56*00b67f09SDavid van Moolenbroek
57*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_invalidate(isc_hmacmd5_t * ctx)58*00b67f09SDavid van Moolenbroek isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
59*00b67f09SDavid van Moolenbroek HMAC_CTX_cleanup(ctx);
60*00b67f09SDavid van Moolenbroek }
61*00b67f09SDavid van Moolenbroek
62*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_update(isc_hmacmd5_t * ctx,const unsigned char * buf,unsigned int len)63*00b67f09SDavid van Moolenbroek isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
64*00b67f09SDavid van Moolenbroek unsigned int len)
65*00b67f09SDavid van Moolenbroek {
66*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
67*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
68*00b67f09SDavid van Moolenbroek #else
69*00b67f09SDavid van Moolenbroek HMAC_Update(ctx, buf, (int) len);
70*00b67f09SDavid van Moolenbroek #endif
71*00b67f09SDavid van Moolenbroek }
72*00b67f09SDavid van Moolenbroek
73*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_sign(isc_hmacmd5_t * ctx,unsigned char * digest)74*00b67f09SDavid van Moolenbroek isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
75*00b67f09SDavid van Moolenbroek #ifdef HMAC_RETURN_INT
76*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(HMAC_Final(ctx, digest, NULL) == 1);
77*00b67f09SDavid van Moolenbroek #else
78*00b67f09SDavid van Moolenbroek HMAC_Final(ctx, digest, NULL);
79*00b67f09SDavid van Moolenbroek #endif
80*00b67f09SDavid van Moolenbroek HMAC_CTX_cleanup(ctx);
81*00b67f09SDavid van Moolenbroek }
82*00b67f09SDavid van Moolenbroek
83*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTOWITHHMAC
84*00b67f09SDavid van Moolenbroek
85*00b67f09SDavid van Moolenbroek static CK_BBOOL truevalue = TRUE;
86*00b67f09SDavid van Moolenbroek static CK_BBOOL falsevalue = FALSE;
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_init(isc_hmacmd5_t * ctx,const unsigned char * key,unsigned int len)89*00b67f09SDavid van Moolenbroek isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
90*00b67f09SDavid van Moolenbroek unsigned int len)
91*00b67f09SDavid van Moolenbroek {
92*00b67f09SDavid van Moolenbroek CK_RV rv;
93*00b67f09SDavid van Moolenbroek CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 };
94*00b67f09SDavid van Moolenbroek CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
95*00b67f09SDavid van Moolenbroek CK_KEY_TYPE keyType = CKK_MD5_HMAC;
96*00b67f09SDavid van Moolenbroek CK_ATTRIBUTE keyTemplate[] =
97*00b67f09SDavid van Moolenbroek {
98*00b67f09SDavid van Moolenbroek { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
99*00b67f09SDavid van Moolenbroek { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
100*00b67f09SDavid van Moolenbroek { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
101*00b67f09SDavid van Moolenbroek { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
102*00b67f09SDavid van Moolenbroek { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
103*00b67f09SDavid van Moolenbroek { CKA_VALUE, NULL, (CK_ULONG) len }
104*00b67f09SDavid van Moolenbroek };
105*00b67f09SDavid van Moolenbroek
106*00b67f09SDavid van Moolenbroek DE_CONST(key, keyTemplate[5].pValue);
107*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
108*00b67f09SDavid van Moolenbroek ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
109*00b67f09SDavid van Moolenbroek ctx->object = CK_INVALID_HANDLE;
110*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_CreateObject,
111*00b67f09SDavid van Moolenbroek (ctx->session, keyTemplate,
112*00b67f09SDavid van Moolenbroek (CK_ULONG) 6, &ctx->object));
113*00b67f09SDavid van Moolenbroek INSIST(ctx->object != CK_INVALID_HANDLE);
114*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
115*00b67f09SDavid van Moolenbroek }
116*00b67f09SDavid van Moolenbroek
117*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_invalidate(isc_hmacmd5_t * ctx)118*00b67f09SDavid van Moolenbroek isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
119*00b67f09SDavid van Moolenbroek CK_BYTE garbage[ISC_MD5_DIGESTLENGTH];
120*00b67f09SDavid van Moolenbroek CK_ULONG len = ISC_MD5_DIGESTLENGTH;
121*00b67f09SDavid van Moolenbroek
122*00b67f09SDavid van Moolenbroek if (ctx->handle == NULL)
123*00b67f09SDavid van Moolenbroek return;
124*00b67f09SDavid van Moolenbroek (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
125*00b67f09SDavid van Moolenbroek memset(garbage, 0, sizeof(garbage));
126*00b67f09SDavid van Moolenbroek if (ctx->object != CK_INVALID_HANDLE)
127*00b67f09SDavid van Moolenbroek (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
128*00b67f09SDavid van Moolenbroek ctx->object = CK_INVALID_HANDLE;
129*00b67f09SDavid van Moolenbroek pk11_return_session(ctx);
130*00b67f09SDavid van Moolenbroek }
131*00b67f09SDavid van Moolenbroek
132*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_update(isc_hmacmd5_t * ctx,const unsigned char * buf,unsigned int len)133*00b67f09SDavid van Moolenbroek isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
134*00b67f09SDavid van Moolenbroek unsigned int len)
135*00b67f09SDavid van Moolenbroek {
136*00b67f09SDavid van Moolenbroek CK_RV rv;
137*00b67f09SDavid van Moolenbroek CK_BYTE_PTR pPart;
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek DE_CONST(buf, pPart);
140*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_SignUpdate,
141*00b67f09SDavid van Moolenbroek (ctx->session, pPart, (CK_ULONG) len));
142*00b67f09SDavid van Moolenbroek }
143*00b67f09SDavid van Moolenbroek
144*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_sign(isc_hmacmd5_t * ctx,unsigned char * digest)145*00b67f09SDavid van Moolenbroek isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
146*00b67f09SDavid van Moolenbroek CK_RV rv;
147*00b67f09SDavid van Moolenbroek CK_ULONG len = ISC_MD5_DIGESTLENGTH;
148*00b67f09SDavid van Moolenbroek
149*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_SignFinal,
150*00b67f09SDavid van Moolenbroek (ctx->session, (CK_BYTE_PTR) digest, &len));
151*00b67f09SDavid van Moolenbroek if (ctx->object != CK_INVALID_HANDLE)
152*00b67f09SDavid van Moolenbroek (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
153*00b67f09SDavid van Moolenbroek ctx->object = CK_INVALID_HANDLE;
154*00b67f09SDavid van Moolenbroek pk11_return_session(ctx);
155*00b67f09SDavid van Moolenbroek }
156*00b67f09SDavid van Moolenbroek
157*00b67f09SDavid van Moolenbroek #elif PKCS11CRYPTO
158*00b67f09SDavid van Moolenbroek
159*00b67f09SDavid van Moolenbroek #define PADLEN 64
160*00b67f09SDavid van Moolenbroek #define IPAD 0x36
161*00b67f09SDavid van Moolenbroek #define OPAD 0x5C
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_init(isc_hmacmd5_t * ctx,const unsigned char * key,unsigned int len)164*00b67f09SDavid van Moolenbroek isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
165*00b67f09SDavid van Moolenbroek unsigned int len)
166*00b67f09SDavid van Moolenbroek {
167*00b67f09SDavid van Moolenbroek CK_RV rv;
168*00b67f09SDavid van Moolenbroek CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
169*00b67f09SDavid van Moolenbroek unsigned char ipad[PADLEN];
170*00b67f09SDavid van Moolenbroek unsigned int i;
171*00b67f09SDavid van Moolenbroek
172*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
173*00b67f09SDavid van Moolenbroek ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
174*00b67f09SDavid van Moolenbroek RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL);
175*00b67f09SDavid van Moolenbroek if (len > PADLEN) {
176*00b67f09SDavid van Moolenbroek CK_BYTE_PTR kPart;
177*00b67f09SDavid van Moolenbroek CK_ULONG kl;
178*00b67f09SDavid van Moolenbroek
179*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
180*00b67f09SDavid van Moolenbroek DE_CONST(key, kPart);
181*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestUpdate,
182*00b67f09SDavid van Moolenbroek (ctx->session, kPart, (CK_ULONG) len));
183*00b67f09SDavid van Moolenbroek kl = ISC_MD5_DIGESTLENGTH;
184*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestFinal,
185*00b67f09SDavid van Moolenbroek (ctx->session, (CK_BYTE_PTR) ctx->key, &kl));
186*00b67f09SDavid van Moolenbroek } else
187*00b67f09SDavid van Moolenbroek memmove(ctx->key, key, len);
188*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
189*00b67f09SDavid van Moolenbroek memset(ipad, IPAD, PADLEN);
190*00b67f09SDavid van Moolenbroek for (i = 0; i < PADLEN; i++)
191*00b67f09SDavid van Moolenbroek ipad[i] ^= ctx->key[i];
192*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestUpdate,
193*00b67f09SDavid van Moolenbroek (ctx->session, ipad, (CK_ULONG) PADLEN));
194*00b67f09SDavid van Moolenbroek }
195*00b67f09SDavid van Moolenbroek
196*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_invalidate(isc_hmacmd5_t * ctx)197*00b67f09SDavid van Moolenbroek isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
198*00b67f09SDavid van Moolenbroek if (ctx->key != NULL)
199*00b67f09SDavid van Moolenbroek pk11_mem_put(ctx->key, PADLEN);
200*00b67f09SDavid van Moolenbroek ctx->key = NULL;
201*00b67f09SDavid van Moolenbroek isc_md5_invalidate(ctx);
202*00b67f09SDavid van Moolenbroek }
203*00b67f09SDavid van Moolenbroek
204*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_update(isc_hmacmd5_t * ctx,const unsigned char * buf,unsigned int len)205*00b67f09SDavid van Moolenbroek isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
206*00b67f09SDavid van Moolenbroek unsigned int len)
207*00b67f09SDavid van Moolenbroek {
208*00b67f09SDavid van Moolenbroek CK_RV rv;
209*00b67f09SDavid van Moolenbroek CK_BYTE_PTR pPart;
210*00b67f09SDavid van Moolenbroek
211*00b67f09SDavid van Moolenbroek DE_CONST(buf, pPart);
212*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestUpdate,
213*00b67f09SDavid van Moolenbroek (ctx->session, pPart, (CK_ULONG) len));
214*00b67f09SDavid van Moolenbroek }
215*00b67f09SDavid van Moolenbroek
216*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_sign(isc_hmacmd5_t * ctx,unsigned char * digest)217*00b67f09SDavid van Moolenbroek isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
218*00b67f09SDavid van Moolenbroek CK_RV rv;
219*00b67f09SDavid van Moolenbroek CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
220*00b67f09SDavid van Moolenbroek CK_ULONG len = ISC_MD5_DIGESTLENGTH;
221*00b67f09SDavid van Moolenbroek CK_BYTE opad[PADLEN];
222*00b67f09SDavid van Moolenbroek unsigned int i;
223*00b67f09SDavid van Moolenbroek
224*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestFinal,
225*00b67f09SDavid van Moolenbroek (ctx->session, (CK_BYTE_PTR) digest,
226*00b67f09SDavid van Moolenbroek (CK_ULONG_PTR) &len));
227*00b67f09SDavid van Moolenbroek memset(opad, OPAD, PADLEN);
228*00b67f09SDavid van Moolenbroek for (i = 0; i < PADLEN; i++)
229*00b67f09SDavid van Moolenbroek opad[i] ^= ctx->key[i];
230*00b67f09SDavid van Moolenbroek pk11_mem_put(ctx->key, PADLEN);
231*00b67f09SDavid van Moolenbroek ctx->key = NULL;
232*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
233*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestUpdate,
234*00b67f09SDavid van Moolenbroek (ctx->session, opad, (CK_ULONG) PADLEN));
235*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestUpdate,
236*00b67f09SDavid van Moolenbroek (ctx->session, (CK_BYTE_PTR) digest, len));
237*00b67f09SDavid van Moolenbroek PK11_FATALCHECK(pkcs_C_DigestFinal,
238*00b67f09SDavid van Moolenbroek (ctx->session,
239*00b67f09SDavid van Moolenbroek (CK_BYTE_PTR) digest,
240*00b67f09SDavid van Moolenbroek (CK_ULONG_PTR) &len));
241*00b67f09SDavid van Moolenbroek pk11_return_session(ctx);
242*00b67f09SDavid van Moolenbroek }
243*00b67f09SDavid van Moolenbroek
244*00b67f09SDavid van Moolenbroek #else
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek #define PADLEN 64
247*00b67f09SDavid van Moolenbroek #define IPAD 0x36
248*00b67f09SDavid van Moolenbroek #define OPAD 0x5C
249*00b67f09SDavid van Moolenbroek
250*00b67f09SDavid van Moolenbroek /*!
251*00b67f09SDavid van Moolenbroek * Start HMAC-MD5 process. Initialize an md5 context and digest the key.
252*00b67f09SDavid van Moolenbroek */
253*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_init(isc_hmacmd5_t * ctx,const unsigned char * key,unsigned int len)254*00b67f09SDavid van Moolenbroek isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
255*00b67f09SDavid van Moolenbroek unsigned int len)
256*00b67f09SDavid van Moolenbroek {
257*00b67f09SDavid van Moolenbroek unsigned char ipad[PADLEN];
258*00b67f09SDavid van Moolenbroek int i;
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek memset(ctx->key, 0, sizeof(ctx->key));
261*00b67f09SDavid van Moolenbroek if (len > sizeof(ctx->key)) {
262*00b67f09SDavid van Moolenbroek isc_md5_t md5ctx;
263*00b67f09SDavid van Moolenbroek isc_md5_init(&md5ctx);
264*00b67f09SDavid van Moolenbroek isc_md5_update(&md5ctx, key, len);
265*00b67f09SDavid van Moolenbroek isc_md5_final(&md5ctx, ctx->key);
266*00b67f09SDavid van Moolenbroek } else
267*00b67f09SDavid van Moolenbroek memmove(ctx->key, key, len);
268*00b67f09SDavid van Moolenbroek
269*00b67f09SDavid van Moolenbroek isc_md5_init(&ctx->md5ctx);
270*00b67f09SDavid van Moolenbroek memset(ipad, IPAD, sizeof(ipad));
271*00b67f09SDavid van Moolenbroek for (i = 0; i < PADLEN; i++)
272*00b67f09SDavid van Moolenbroek ipad[i] ^= ctx->key[i];
273*00b67f09SDavid van Moolenbroek isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
274*00b67f09SDavid van Moolenbroek }
275*00b67f09SDavid van Moolenbroek
276*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_invalidate(isc_hmacmd5_t * ctx)277*00b67f09SDavid van Moolenbroek isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
278*00b67f09SDavid van Moolenbroek isc_md5_invalidate(&ctx->md5ctx);
279*00b67f09SDavid van Moolenbroek memset(ctx->key, 0, sizeof(ctx->key));
280*00b67f09SDavid van Moolenbroek }
281*00b67f09SDavid van Moolenbroek
282*00b67f09SDavid van Moolenbroek /*!
283*00b67f09SDavid van Moolenbroek * Update context to reflect the concatenation of another buffer full
284*00b67f09SDavid van Moolenbroek * of bytes.
285*00b67f09SDavid van Moolenbroek */
286*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_update(isc_hmacmd5_t * ctx,const unsigned char * buf,unsigned int len)287*00b67f09SDavid van Moolenbroek isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
288*00b67f09SDavid van Moolenbroek unsigned int len)
289*00b67f09SDavid van Moolenbroek {
290*00b67f09SDavid van Moolenbroek isc_md5_update(&ctx->md5ctx, buf, len);
291*00b67f09SDavid van Moolenbroek }
292*00b67f09SDavid van Moolenbroek
293*00b67f09SDavid van Moolenbroek /*!
294*00b67f09SDavid van Moolenbroek * Compute signature - finalize MD5 operation and reapply MD5.
295*00b67f09SDavid van Moolenbroek */
296*00b67f09SDavid van Moolenbroek void
isc_hmacmd5_sign(isc_hmacmd5_t * ctx,unsigned char * digest)297*00b67f09SDavid van Moolenbroek isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
298*00b67f09SDavid van Moolenbroek unsigned char opad[PADLEN];
299*00b67f09SDavid van Moolenbroek int i;
300*00b67f09SDavid van Moolenbroek
301*00b67f09SDavid van Moolenbroek isc_md5_final(&ctx->md5ctx, digest);
302*00b67f09SDavid van Moolenbroek
303*00b67f09SDavid van Moolenbroek memset(opad, OPAD, sizeof(opad));
304*00b67f09SDavid van Moolenbroek for (i = 0; i < PADLEN; i++)
305*00b67f09SDavid van Moolenbroek opad[i] ^= ctx->key[i];
306*00b67f09SDavid van Moolenbroek
307*00b67f09SDavid van Moolenbroek isc_md5_init(&ctx->md5ctx);
308*00b67f09SDavid van Moolenbroek isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
309*00b67f09SDavid van Moolenbroek isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
310*00b67f09SDavid van Moolenbroek isc_md5_final(&ctx->md5ctx, digest);
311*00b67f09SDavid van Moolenbroek isc_hmacmd5_invalidate(ctx);
312*00b67f09SDavid van Moolenbroek }
313*00b67f09SDavid van Moolenbroek
314*00b67f09SDavid van Moolenbroek #endif /* !ISC_PLATFORM_OPENSSLHASH */
315*00b67f09SDavid van Moolenbroek
316*00b67f09SDavid van Moolenbroek /*!
317*00b67f09SDavid van Moolenbroek * Verify signature - finalize MD5 operation and reapply MD5, then
318*00b67f09SDavid van Moolenbroek * compare to the supplied digest.
319*00b67f09SDavid van Moolenbroek */
320*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacmd5_verify(isc_hmacmd5_t * ctx,unsigned char * digest)321*00b67f09SDavid van Moolenbroek isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
322*00b67f09SDavid van Moolenbroek return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
323*00b67f09SDavid van Moolenbroek }
324*00b67f09SDavid van Moolenbroek
325*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_hmacmd5_verify2(isc_hmacmd5_t * ctx,unsigned char * digest,size_t len)326*00b67f09SDavid van Moolenbroek isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
327*00b67f09SDavid van Moolenbroek unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
328*00b67f09SDavid van Moolenbroek
329*00b67f09SDavid van Moolenbroek REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
330*00b67f09SDavid van Moolenbroek isc_hmacmd5_sign(ctx, newdigest);
331*00b67f09SDavid van Moolenbroek return (isc_safe_memcmp(digest, newdigest, len));
332*00b67f09SDavid van Moolenbroek }
333