Git init
[external/xmlsec1.git] / src / nss / hmac.c
1 /** 
2  * XMLSec library
3  *
4  * This is free software; see Copyright file in the source
5  * distribution for preciese wording.
6  * 
7  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
8  * Copyright (c) 2003 America Online, Inc.  All rights reserved.
9  */
10 #ifndef XMLSEC_NO_HMAC
11 #include "globals.h"
12
13 #include <string.h>
14
15 #include <nspr.h>
16 #include <nss.h>
17 #include <secoid.h>
18 #include <pk11func.h>
19
20 #include <xmlsec/xmlsec.h>
21 #include <xmlsec/xmltree.h>
22 #include <xmlsec/keys.h>
23 #include <xmlsec/transforms.h>
24 #include <xmlsec/errors.h>
25
26 #include <xmlsec/nss/app.h>
27 #include <xmlsec/nss/crypto.h>
28
29 /* sizes in bits */
30 #define XMLSEC_NSS_MIN_HMAC_SIZE                80
31 #define XMLSEC_NSS_MAX_HMAC_SIZE                (128 * 8)
32
33 /**************************************************************************
34  *
35  * Configuration
36  *
37  *****************************************************************************/
38 static int g_xmlsec_nss_hmac_min_length = XMLSEC_NSS_MIN_HMAC_SIZE;
39
40 /**
41  * xmlSecNssHmacGetMinOutputLength: 
42  * 
43  * Gets the value of min HMAC length.
44  * 
45  * Returns: the min HMAC output length
46  */
47 int xmlSecNssHmacGetMinOutputLength(void)
48 {
49     return g_xmlsec_nss_hmac_min_length;
50 }
51
52 /**
53  * xmlSecNssHmacSetMinOutputLength: 
54  * @min_length: the new min length 
55  * 
56  * Sets the min HMAC output length
57  */
58 void xmlSecNssHmacSetMinOutputLength(int min_length)
59 {
60     g_xmlsec_nss_hmac_min_length = min_length;
61 }
62
63 /**************************************************************************
64  *
65  * Internal NSS HMAC CTX
66  *
67  *****************************************************************************/
68 typedef struct _xmlSecNssHmacCtx                xmlSecNssHmacCtx, *xmlSecNssHmacCtxPtr;
69 struct _xmlSecNssHmacCtx {
70     CK_MECHANISM_TYPE   digestType;
71     PK11Context*        digestCtx;
72     xmlSecByte          dgst[XMLSEC_NSS_MAX_HMAC_SIZE / 8];
73     xmlSecSize          dgstSize;       /* dgst size in bits */
74 };          
75
76 /******************************************************************************
77  *
78  * HMAC transforms
79  *
80  * xmlSecNssHmacCtx is located after xmlSecTransform
81  *
82  *****************************************************************************/
83 #define xmlSecNssHmacGetCtx(transform) \
84     ((xmlSecNssHmacCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
85 #define xmlSecNssHmacSize       \
86     (sizeof(xmlSecTransform) + sizeof(xmlSecNssHmacCtx))
87 #define xmlSecNssHmacCheckId(transform) \
88     (xmlSecTransformCheckId((transform), xmlSecNssTransformHmacSha1Id) || \
89      xmlSecTransformCheckId((transform), xmlSecNssTransformHmacMd5Id) || \
90      xmlSecTransformCheckId((transform), xmlSecNssTransformHmacRipemd160Id))
91
92 static int      xmlSecNssHmacInitialize                 (xmlSecTransformPtr transform);
93 static void     xmlSecNssHmacFinalize                   (xmlSecTransformPtr transform);
94 static int      xmlSecNssHmacNodeRead                   (xmlSecTransformPtr transform,
95                                                          xmlNodePtr node,
96                                                          xmlSecTransformCtxPtr transformCtx);
97 static int      xmlSecNssHmacSetKeyReq                  (xmlSecTransformPtr transform, 
98                                                          xmlSecKeyReqPtr keyReq);
99 static int      xmlSecNssHmacSetKey                     (xmlSecTransformPtr transform, 
100                                                          xmlSecKeyPtr key);
101 static int      xmlSecNssHmacVerify                     (xmlSecTransformPtr transform, 
102                                                          const xmlSecByte* data, 
103                                                          xmlSecSize dataSize,
104                                                          xmlSecTransformCtxPtr transformCtx);
105 static int      xmlSecNssHmacExecute                    (xmlSecTransformPtr transform, 
106                                                          int last, 
107                                                          xmlSecTransformCtxPtr transformCtx);
108
109 static int 
110 xmlSecNssHmacInitialize(xmlSecTransformPtr transform) {
111     xmlSecNssHmacCtxPtr ctx;
112
113     xmlSecAssert2(xmlSecNssHmacCheckId(transform), -1);
114     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
115
116     ctx = xmlSecNssHmacGetCtx(transform);
117     xmlSecAssert2(ctx != NULL, -1);
118     
119     memset(ctx, 0, sizeof(xmlSecNssHmacCtx));
120     if(xmlSecTransformCheckId(transform, xmlSecNssTransformHmacSha1Id)) {
121         ctx->digestType = CKM_SHA_1_HMAC;
122     } else if(xmlSecTransformCheckId(transform, xmlSecNssTransformHmacMd5Id)) {
123         ctx->digestType = CKM_MD5_HMAC;
124     } else if(xmlSecTransformCheckId(transform, xmlSecNssTransformHmacRipemd160Id)) {
125         ctx->digestType = CKM_RIPEMD160_HMAC;
126     } else {
127         xmlSecError(XMLSEC_ERRORS_HERE, 
128                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
129                     NULL,
130                     XMLSEC_ERRORS_R_INVALID_TRANSFORM,
131                     XMLSEC_ERRORS_NO_MESSAGE);
132         return(-1);
133     }
134     return(0);
135 }
136
137 static void 
138 xmlSecNssHmacFinalize(xmlSecTransformPtr transform) {
139     xmlSecNssHmacCtxPtr ctx;
140
141     xmlSecAssert(xmlSecNssHmacCheckId(transform));    
142     xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize));
143
144     ctx = xmlSecNssHmacGetCtx(transform);
145     xmlSecAssert(ctx != NULL);
146
147     if(ctx->digestCtx != NULL) {
148         PK11_DestroyContext(ctx->digestCtx, PR_TRUE);
149     }
150     memset(ctx, 0, sizeof(xmlSecNssHmacCtx));
151 }
152
153 /**
154  * xmlSecNssHmacNodeRead:
155  *
156  * HMAC (http://www.w3.org/TR/xmldsig-core/#sec-HMAC):
157  *
158  * The HMAC algorithm (RFC2104 [HMAC]) takes the truncation length in bits 
159  * as a parameter; if the parameter is not specified then all the bits of the 
160  * hash are output. An example of an HMAC SignatureMethod element:  
161  * <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1">
162  *   <HMACOutputLength>128</HMACOutputLength>
163  * </SignatureMethod>
164  * 
165  * Schema Definition:
166  * 
167  * <simpleType name="HMACOutputLengthType">
168  *   <restriction base="integer"/>
169  * </simpleType>
170  *     
171  * DTD:
172  *     
173  * <!ELEMENT HMACOutputLength (#PCDATA)>
174  */
175 static int
176 xmlSecNssHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
177     xmlSecNssHmacCtxPtr ctx;
178     xmlNodePtr cur;
179
180     xmlSecAssert2(xmlSecNssHmacCheckId(transform), -1);
181     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
182     xmlSecAssert2(node!= NULL, -1);
183     xmlSecAssert2(transformCtx!= NULL, -1);
184
185     ctx = xmlSecNssHmacGetCtx(transform);
186     xmlSecAssert2(ctx != NULL, -1);
187
188     cur = xmlSecGetNextElementNode(node->children); 
189     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) {  
190         xmlChar *content;
191         
192         content = xmlNodeGetContent(cur);
193         if(content != NULL) {
194             ctx->dgstSize = atoi((char*)content);           
195             xmlFree(content);
196         }
197
198         /* Ensure that HMAC length is greater than min specified.
199            Otherwise, an attacker can set this lenght to 0 or very 
200            small value
201         */
202         if((int)ctx->dgstSize < xmlSecNssHmacGetMinOutputLength()) {
203            xmlSecError(XMLSEC_ERRORS_HERE,
204                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
205                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
206                     XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
207                     "HMAC output length is too small");
208            return(-1);
209         }
210
211         cur = xmlSecGetNextElementNode(cur->next);
212     }
213     
214     if(cur != NULL) {
215         xmlSecError(XMLSEC_ERRORS_HERE,
216                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
217                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
218                     XMLSEC_ERRORS_R_INVALID_NODE,
219                     "no nodes expected");
220         return(-1);
221     }
222     return(0); 
223 }
224
225
226 static int  
227 xmlSecNssHmacSetKeyReq(xmlSecTransformPtr transform,  xmlSecKeyReqPtr keyReq) {
228     xmlSecNssHmacCtxPtr ctx;
229
230     xmlSecAssert2(xmlSecNssHmacCheckId(transform), -1);
231     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
232     xmlSecAssert2(keyReq != NULL, -1);
233     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
234
235     ctx = xmlSecNssHmacGetCtx(transform);
236     xmlSecAssert2(ctx != NULL, -1);
237
238     keyReq->keyId  = xmlSecNssKeyDataHmacId;
239     keyReq->keyType= xmlSecKeyDataTypeSymmetric;
240     if(transform->operation == xmlSecTransformOperationSign) {
241         keyReq->keyUsage = xmlSecKeyUsageSign;
242     } else {
243         keyReq->keyUsage = xmlSecKeyUsageVerify;
244     }
245     
246     return(0);
247 }
248
249 static int
250 xmlSecNssHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
251     xmlSecNssHmacCtxPtr ctx;
252     xmlSecKeyDataPtr value;
253     xmlSecBufferPtr buffer;
254     SECItem keyItem;
255     SECItem ignore;
256     PK11SlotInfo* slot;
257     PK11SymKey* symKey;
258     
259     xmlSecAssert2(xmlSecNssHmacCheckId(transform), -1);
260     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
261     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
262     xmlSecAssert2(key != NULL, -1);
263
264     ctx = xmlSecNssHmacGetCtx(transform);
265     xmlSecAssert2(ctx != NULL, -1);
266     xmlSecAssert2(ctx->digestType != 0, -1);
267     xmlSecAssert2(ctx->digestCtx == NULL, -1);
268     
269     value = xmlSecKeyGetValue(key);
270     xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecNssKeyDataHmacId), -1);
271
272     buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
273     xmlSecAssert2(buffer != NULL, -1);
274
275     if(xmlSecBufferGetSize(buffer) == 0) {
276         xmlSecError(XMLSEC_ERRORS_HERE, 
277                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
278                     NULL,
279                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
280                     "key is empty");
281         return(-1);    
282     }
283
284     memset(&ignore, 0, sizeof(ignore));
285     memset(&keyItem, 0, sizeof(keyItem));
286     keyItem.data = xmlSecBufferGetData(buffer);
287     keyItem.len  = xmlSecBufferGetSize(buffer); 
288
289     slot = PK11_GetBestSlot(ctx->digestType, NULL);
290     if(slot == NULL) {
291         xmlSecError(XMLSEC_ERRORS_HERE, 
292                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
293                     "PK11_GetBestSlot",
294                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
295                     XMLSEC_ERRORS_NO_MESSAGE);
296         return(-1);
297     }
298         
299     symKey = PK11_ImportSymKey(slot, ctx->digestType, PK11_OriginDerive, 
300                                CKA_SIGN, &keyItem, NULL);
301     if(symKey == NULL) {
302         xmlSecError(XMLSEC_ERRORS_HERE, 
303                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
304                     "PK11_ImportSymKey",
305                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
306                     "error code=%d", PORT_GetError());
307         PK11_FreeSlot(slot);
308         return(-1);
309     }
310
311     ctx->digestCtx = PK11_CreateContextBySymKey(ctx->digestType, CKA_SIGN, symKey, &ignore);
312     if(ctx->digestCtx == NULL) {
313         xmlSecError(XMLSEC_ERRORS_HERE, 
314                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
315                     "PK11_CreateContextBySymKey",
316                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
317                     "error code=%d", PORT_GetError());
318         PK11_FreeSymKey(symKey);
319         PK11_FreeSlot(slot);
320         return(-1);
321     }
322
323     PK11_FreeSymKey(symKey);
324     PK11_FreeSlot(slot);
325     return(0);
326 }
327
328 static int
329 xmlSecNssHmacVerify(xmlSecTransformPtr transform, 
330                         const xmlSecByte* data, xmlSecSize dataSize,
331                         xmlSecTransformCtxPtr transformCtx) {
332     static xmlSecByte last_byte_masks[] =       
333                 { 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
334
335     xmlSecNssHmacCtxPtr ctx;
336     xmlSecByte mask;
337         
338     xmlSecAssert2(xmlSecTransformIsValid(transform), -1);
339     xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1);
340     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
341     xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1);
342     xmlSecAssert2(data != NULL, -1);
343     xmlSecAssert2(transformCtx != NULL, -1);
344
345     ctx = xmlSecNssHmacGetCtx(transform);
346     xmlSecAssert2(ctx != NULL, -1);
347     xmlSecAssert2(ctx->digestCtx != NULL, -1);
348     xmlSecAssert2(ctx->dgstSize > 0, -1);
349     
350     /* compare the digest size in bytes */
351     if(dataSize != ((ctx->dgstSize + 7) / 8)){
352         xmlSecError(XMLSEC_ERRORS_HERE, 
353                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
354                     NULL,
355                     XMLSEC_ERRORS_R_INVALID_SIZE,
356                     "data=%d;dgst=%d",
357                     dataSize, ((ctx->dgstSize + 7) / 8));
358         transform->status = xmlSecTransformStatusFail;
359         return(0);
360     }
361
362     /* we check the last byte separatelly */
363     xmlSecAssert2(dataSize > 0, -1);
364     mask = last_byte_masks[ctx->dgstSize % 8];
365     if((ctx->dgst[dataSize - 1] & mask) != (data[dataSize - 1]  & mask)) {
366         xmlSecError(XMLSEC_ERRORS_HERE, 
367                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
368                     NULL,
369                     XMLSEC_ERRORS_R_DATA_NOT_MATCH,
370                     "data and digest do not match (last byte)");
371         transform->status = xmlSecTransformStatusFail;
372         return(0);
373     }
374
375     /* now check the rest of the digest */
376     if((dataSize > 1) && (memcmp(ctx->dgst, data, dataSize - 1) != 0)) {
377         xmlSecError(XMLSEC_ERRORS_HERE, 
378                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
379                     NULL,
380                     XMLSEC_ERRORS_R_DATA_NOT_MATCH,
381                     "data and digest do not match");
382         transform->status = xmlSecTransformStatusFail;
383         return(0);
384     }
385     
386     transform->status = xmlSecTransformStatusOk;
387     return(0);
388 }
389
390 static int 
391 xmlSecNssHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
392     xmlSecNssHmacCtxPtr ctx;
393     xmlSecBufferPtr in, out;
394     SECStatus rv;
395     int ret;
396     
397     xmlSecAssert2(xmlSecNssHmacCheckId(transform), -1);
398     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
399     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssHmacSize), -1);
400     xmlSecAssert2(transformCtx != NULL, -1);
401
402     ctx = xmlSecNssHmacGetCtx(transform);
403     xmlSecAssert2(ctx != NULL, -1);
404     xmlSecAssert2(ctx->digestCtx != NULL, -1);
405
406     in = &(transform->inBuf);
407     out = &(transform->outBuf);
408
409     if(transform->status == xmlSecTransformStatusNone) {
410         rv = PK11_DigestBegin(ctx->digestCtx);
411         if(rv != SECSuccess) {
412             xmlSecError(XMLSEC_ERRORS_HERE, 
413                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
414                         "PK11_DigestBegin",
415                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
416                         "error code=%d", PORT_GetError());
417             return(-1);
418         }
419         transform->status = xmlSecTransformStatusWorking;
420     }
421     
422     if(transform->status == xmlSecTransformStatusWorking) {
423         xmlSecSize inSize;
424
425         inSize = xmlSecBufferGetSize(in);
426         if(inSize > 0) {
427             rv = PK11_DigestOp(ctx->digestCtx, xmlSecBufferGetData(in), inSize);
428             if (rv != SECSuccess) {
429                 xmlSecError(XMLSEC_ERRORS_HERE, 
430                             xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
431                             "PK11_DigestOp",
432                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
433                             "error code=%d", PORT_GetError());
434                 return(-1);
435             }
436             
437             ret = xmlSecBufferRemoveHead(in, inSize);
438             if(ret < 0) {
439                 xmlSecError(XMLSEC_ERRORS_HERE, 
440                             xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
441                             "xmlSecBufferRemoveHead",
442                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
443                             "size=%d", inSize);
444                 return(-1);
445             }
446         }
447         if(last) {
448             xmlSecSize dgstSize;
449
450             rv = PK11_DigestFinal(ctx->digestCtx, ctx->dgst, &dgstSize, sizeof(ctx->dgst));
451             if(rv != SECSuccess) {
452                 xmlSecError(XMLSEC_ERRORS_HERE, 
453                             xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
454                             "PK11_DigestFinal",
455                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
456                             "error code=%d", PORT_GetError());
457                 return(-1);
458             }
459             xmlSecAssert2(dgstSize > 0, -1);
460
461             /* check/set the result digest size */
462             if(ctx->dgstSize == 0) {
463                 ctx->dgstSize = dgstSize * 8; /* no dgst size specified, use all we have */
464             } else if(ctx->dgstSize <= 8 * dgstSize) {
465                 dgstSize = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */
466             } else {
467                 xmlSecError(XMLSEC_ERRORS_HERE, 
468                             xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
469                             NULL,
470                             XMLSEC_ERRORS_R_INVALID_SIZE,
471                             "result-bits=%d;required-bits=%d",
472                             8 * dgstSize, ctx->dgstSize);
473                 return(-1);
474             }
475
476             if(transform->operation == xmlSecTransformOperationSign) {
477                 ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize);
478                 if(ret < 0) {
479                     xmlSecError(XMLSEC_ERRORS_HERE, 
480                                 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
481                                 "xmlSecBufferAppend",
482                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
483                                 "size=%d", dgstSize);
484                     return(-1);
485                 }
486             }
487             transform->status = xmlSecTransformStatusFinished;
488         }
489     } else if(transform->status == xmlSecTransformStatusFinished) {
490         /* the only way we can get here is if there is no input */
491         xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
492     } else {
493         xmlSecError(XMLSEC_ERRORS_HERE, 
494                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
495                     NULL,
496                     XMLSEC_ERRORS_R_INVALID_STATUS,
497                     "size=%d", transform->status);
498         return(-1);
499     }
500     
501     return(0);
502 }
503
504 /** 
505  * HMAC SHA1
506  */
507 static xmlSecTransformKlass xmlSecNssHmacSha1Klass = {
508     /* klass/object sizes */
509     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
510     xmlSecNssHmacSize,                          /* xmlSecSize objSize */
511
512     xmlSecNameHmacSha1,                         /* const xmlChar* name; */
513     xmlSecHrefHmacSha1,                         /* const xmlChar* href; */
514     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
515     
516     xmlSecNssHmacInitialize,                    /* xmlSecTransformInitializeMethod initialize; */
517     xmlSecNssHmacFinalize,                      /* xmlSecTransformFinalizeMethod finalize; */
518     xmlSecNssHmacNodeRead,                      /* xmlSecTransformNodeReadMethod readNode; */
519     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */    
520     xmlSecNssHmacSetKeyReq,                     /* xmlSecTransformSetKeyReqMethod setKeyReq; */
521     xmlSecNssHmacSetKey,                        /* xmlSecTransformSetKeyMethod setKey; */
522     xmlSecNssHmacVerify,                        /* xmlSecTransformValidateMethod validate; */
523     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
524     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
525     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
526     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
527     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
528     xmlSecNssHmacExecute,                       /* xmlSecTransformExecuteMethod execute; */
529     
530     NULL,                                       /* void* reserved0; */
531     NULL,                                       /* void* reserved1; */
532 };
533
534 /** 
535  * xmlSecNssTransformHmacSha1GetKlass:
536  *
537  * The HMAC-SHA1 transform klass.
538  *
539  * Returns: the HMAC-SHA1 transform klass.
540  */
541 xmlSecTransformId 
542 xmlSecNssTransformHmacSha1GetKlass(void) {
543     return(&xmlSecNssHmacSha1Klass);
544 }
545
546 /** 
547  * HMAC Ripemd160
548  */
549 static xmlSecTransformKlass xmlSecNssHmacRipemd160Klass = {
550     /* klass/object sizes */
551     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
552     xmlSecNssHmacSize,                          /* xmlSecSize objSize */
553
554     xmlSecNameHmacRipemd160,                    /* const xmlChar* name; */
555     xmlSecHrefHmacRipemd160,                    /* const xmlChar* href; */
556     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
557     
558     xmlSecNssHmacInitialize,                    /* xmlSecTransformInitializeMethod initialize; */
559     xmlSecNssHmacFinalize,                      /* xmlSecTransformFinalizeMethod finalize; */
560     xmlSecNssHmacNodeRead,                      /* xmlSecTransformNodeReadMethod readNode; */
561     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */    
562     xmlSecNssHmacSetKeyReq,                     /* xmlSecTransformSetKeyReqMethod setKeyReq; */
563     xmlSecNssHmacSetKey,                        /* xmlSecTransformSetKeyMethod setKey; */
564     xmlSecNssHmacVerify,                        /* xmlSecTransformValidateMethod validate; */
565     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
566     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
567     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
568     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
569     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
570     xmlSecNssHmacExecute,                       /* xmlSecTransformExecuteMethod execute; */
571     
572     NULL,                                       /* void* reserved0; */
573     NULL,                                       /* void* reserved1; */
574 };
575
576 /** 
577  * xmlSecNssTransformHmacRipemd160GetKlass:
578  *
579  * The HMAC-RIPEMD160 transform klass.
580  *
581  * Returns: the HMAC-RIPEMD160 transform klass.
582  */
583 xmlSecTransformId 
584 xmlSecNssTransformHmacRipemd160GetKlass(void) {
585     return(&xmlSecNssHmacRipemd160Klass);
586 }
587
588 /** 
589  * HMAC Md5
590  */
591 static xmlSecTransformKlass xmlSecNssHmacMd5Klass = {
592     /* klass/object sizes */
593     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
594     xmlSecNssHmacSize,                          /* xmlSecSize objSize */
595
596     xmlSecNameHmacMd5,                          /* const xmlChar* name; */
597     xmlSecHrefHmacMd5,                          /* const xmlChar* href; */
598     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
599     
600     xmlSecNssHmacInitialize,                    /* xmlSecTransformInitializeMethod initialize; */
601     xmlSecNssHmacFinalize,                      /* xmlSecTransformFinalizeMethod finalize; */
602     xmlSecNssHmacNodeRead,                      /* xmlSecTransformNodeReadMethod readNode; */
603     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */    
604     xmlSecNssHmacSetKeyReq,                     /* xmlSecTransformSetKeyReqMethod setKeyReq; */
605     xmlSecNssHmacSetKey,                        /* xmlSecTransformSetKeyMethod setKey; */
606     xmlSecNssHmacVerify,                        /* xmlSecTransformValidateMethod validate; */
607     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
608     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
609     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
610     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
611     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
612     xmlSecNssHmacExecute,                       /* xmlSecTransformExecuteMethod execute; */
613     
614     NULL,                                       /* void* reserved0; */
615     NULL,                                       /* void* reserved1; */
616 };
617
618 /** 
619  * xmlSecNssTransformHmacMd5GetKlass:
620  *
621  * The HMAC-MD5 transform klass.
622  *
623  * Returns: the HMAC-MD5 transform klass.
624  */
625 xmlSecTransformId 
626 xmlSecNssTransformHmacMd5GetKlass(void) {
627     return(&xmlSecNssHmacMd5Klass);
628 }
629
630
631 #endif /* XMLSEC_NO_HMAC */
632
633