1 /*
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  *
5  * This is free software; see Copyright file in the source
6  * distribution for preciese wording.
7  *
8  * Copyright (C) 2018 Miklos Vajna. All Rights Reserved.
9  */
10 /**
11  * SECTION:hmac
12  * @Short_description: HMAC transforms implementation for Microsoft Cryptography API: Next Generation (CNG).
13  * @Stability: Private
14  *
15  */
16 
17 #ifndef XMLSEC_NO_HMAC
18 #include "globals.h"
19 
20 #include <string.h>
21 
22 #define WIN32_NO_STATUS
23 #include <windows.h>
24 #undef WIN32_NO_STATUS
25 #include <ntstatus.h>
26 #include <bcrypt.h>
27 #include <ncrypt.h>
28 
29 #include <xmlsec/xmlsec.h>
30 #include <xmlsec/xmltree.h>
31 #include <xmlsec/keys.h>
32 #include <xmlsec/keyinfo.h>
33 #include <xmlsec/transforms.h>
34 #include <xmlsec/errors.h>
35 #include <xmlsec/bn.h>
36 
37 #include <xmlsec/mscng/crypto.h>
38 
39 typedef struct _xmlSecMSCngHmacCtx xmlSecMSCngHmacCtx, *xmlSecMSCngHmacCtxPtr;
40 
41 struct _xmlSecMSCngHmacCtx {
42     LPCWSTR pszAlgId;
43     int initialized;
44     BCRYPT_ALG_HANDLE hAlg;
45     PBYTE hash;
46     DWORD hashLength;
47     /* truncation length in bits */
48     DWORD truncationLength;
49     BCRYPT_HASH_HANDLE hHash;
50 };
51 
52 #define xmlSecMSCngHmacGetCtx(data) \
53     ((xmlSecMSCngHmacCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecTransform)))
54 #define xmlSecMSCngHmacSize \
55     (sizeof(xmlSecTransform) + sizeof(xmlSecMSCngHmacCtx))
56 
57 static int
xmlSecMSCngHmacCheckId(xmlSecTransformPtr transform)58 xmlSecMSCngHmacCheckId(xmlSecTransformPtr transform) {
59 
60 #ifndef XMLSEC_NO_MD5
61     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacMd5Id)) {
62         return(1);
63     } else
64 #endif /* XMLSEC_NO_MD5 */
65 
66 #ifndef XMLSEC_NO_SHA1
67     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha1Id)) {
68         return(1);
69     } else
70 #endif /* XMLSEC_NO_SHA1 */
71 
72 #ifndef XMLSEC_NO_SHA256
73     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha256Id)) {
74         return(1);
75     } else
76 #endif /* XMLSEC_NO_SHA256 */
77 
78 #ifndef XMLSEC_NO_SHA384
79     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha384Id)) {
80         return(1);
81     } else
82 #endif /* XMLSEC_NO_SHA384 */
83 
84 #ifndef XMLSEC_NO_SHA512
85     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha512Id)) {
86         return(1);
87     } else
88 #endif /* XMLSEC_NO_SHA512 */
89 
90     /* not found */
91     {
92         return(0);
93     }
94 }
95 static int
xmlSecMSCngHmacInitialize(xmlSecTransformPtr transform)96 xmlSecMSCngHmacInitialize(xmlSecTransformPtr transform) {
97     xmlSecMSCngHmacCtxPtr ctx;
98 
99     xmlSecAssert2(xmlSecMSCngHmacCheckId(transform), -1);
100     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
101 
102     ctx = xmlSecMSCngHmacGetCtx(transform);
103     xmlSecAssert2(ctx != NULL, -1);
104 
105     /* initialize context */
106     memset(ctx, 0, sizeof(xmlSecMSCngHmacCtx));
107 
108 #ifndef XMLSEC_NO_MD5
109     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacMd5Id)) {
110         ctx->pszAlgId = BCRYPT_MD5_ALGORITHM;
111     } else
112 #endif /* XMLSEC_NO_MD5 */
113 
114 #ifndef XMLSEC_NO_SHA1
115     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha1Id)) {
116         ctx->pszAlgId = BCRYPT_SHA1_ALGORITHM;
117     } else
118 #endif /* XMLSEC_NO_SHA1 */
119 
120 #ifndef XMLSEC_NO_SHA256
121     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha256Id)) {
122         ctx->pszAlgId = BCRYPT_SHA256_ALGORITHM;
123     } else
124 #endif /* XMLSEC_NO_SHA256 */
125 
126 #ifndef XMLSEC_NO_SHA384
127     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha384Id)) {
128         ctx->pszAlgId = BCRYPT_SHA384_ALGORITHM;
129     } else
130 #endif /* XMLSEC_NO_SHA384 */
131 
132 #ifndef XMLSEC_NO_SHA512
133     if(xmlSecTransformCheckId(transform, xmlSecMSCngTransformHmacSha512Id)) {
134         ctx->pszAlgId = BCRYPT_SHA512_ALGORITHM;
135     } else
136 #endif /* XMLSEC_NO_SHA512 */
137 
138     /* not found */
139     {
140         xmlSecInvalidTransfromError(transform)
141         return(-1);
142     }
143 
144     return(0);
145 }
146 
147 static void
xmlSecMSCngHmacFinalize(xmlSecTransformPtr transform)148 xmlSecMSCngHmacFinalize(xmlSecTransformPtr transform) {
149     xmlSecMSCngHmacCtxPtr ctx;
150 
151     xmlSecAssert(xmlSecMSCngHmacCheckId(transform));
152     xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize));
153 
154     ctx = xmlSecMSCngHmacGetCtx(transform);
155     xmlSecAssert(ctx != NULL);
156 
157     if(ctx->hash != NULL) {
158         xmlFree(ctx->hash);
159     }
160 
161     if(ctx->hHash != NULL) {
162         BCryptDestroyHash(ctx->hHash);
163     }
164 
165     if(ctx->hAlg != NULL) {
166         BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
167     }
168 
169     memset(ctx, 0, sizeof(xmlSecMSCngHmacCtx));
170 }
171 
172 static int
xmlSecMSCngHmacNodeRead(xmlSecTransformPtr transform,xmlNodePtr node,xmlSecTransformCtxPtr transformCtx)173 xmlSecMSCngHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
174     xmlSecMSCngHmacCtxPtr ctx;
175     xmlNodePtr cur;
176 
177     xmlSecAssert2(xmlSecMSCngHmacCheckId(transform), -1);
178     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
179     xmlSecAssert2(node!= NULL, -1);
180     xmlSecAssert2(transformCtx != NULL, -1);
181 
182     ctx = xmlSecMSCngHmacGetCtx(transform);
183     xmlSecAssert2(ctx != NULL, -1);
184 
185     cur = xmlSecGetNextElementNode(node->children);
186     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) {
187         xmlChar *content;
188 
189         content = xmlNodeGetContent(cur);
190         if(content != NULL) {
191             ctx->truncationLength = atoi((char*)content);
192             xmlFree(content);
193         }
194 
195 	/* 80 is a minimum value from
196 	 * <https://www.w3.org/TR/xmldsig-core1/#sec-SignatureMethod> */
197         if((int)ctx->truncationLength < 80) {
198             xmlSecInvalidNodeContentError(cur, xmlSecTransformGetName(transform),
199                                           "HMAC output length is too small");
200             return(-1);
201         }
202 
203         cur = xmlSecGetNextElementNode(cur->next);
204     }
205 
206     if(cur != NULL) {
207         xmlSecUnexpectedNodeError(cur, xmlSecTransformGetName(transform));
208         return(-1);
209     }
210 
211     return(0);
212 }
213 
214 static int
xmlSecMSCngHmacSetKeyReq(xmlSecTransformPtr transform,xmlSecKeyReqPtr keyReq)215 xmlSecMSCngHmacSetKeyReq(xmlSecTransformPtr transform,  xmlSecKeyReqPtr keyReq) {
216     xmlSecAssert2(xmlSecMSCngHmacCheckId(transform), -1);
217     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
218     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
219     xmlSecAssert2(keyReq != NULL, -1);
220 
221     keyReq->keyId = xmlSecMSCngKeyDataHmacId;
222     keyReq->keyType = xmlSecKeyDataTypeSymmetric;
223     if(transform->operation == xmlSecTransformOperationSign) {
224         keyReq->keyUsage = xmlSecKeyUsageSign;
225     } else {
226         keyReq->keyUsage = xmlSecKeyUsageVerify;
227     }
228 
229     return(0);
230 }
231 
232 static int
xmlSecMSCngHmacSetKey(xmlSecTransformPtr transform,xmlSecKeyPtr key)233 xmlSecMSCngHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
234     xmlSecMSCngHmacCtxPtr ctx;
235     xmlSecKeyDataPtr value;
236     xmlSecBufferPtr buffer;
237     DWORD resultLength = 0;
238     NTSTATUS status;
239 
240     xmlSecAssert2(xmlSecMSCngHmacCheckId(transform), -1);
241     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
242     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
243     xmlSecAssert2(key != NULL, -1);
244 
245     ctx = xmlSecMSCngHmacGetCtx(transform);
246     xmlSecAssert2(ctx != NULL, -1);
247     xmlSecAssert2(ctx->initialized == 0, -1);
248 
249     value = xmlSecKeyGetValue(key);
250     xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecMSCngKeyDataHmacId), -1);
251 
252     buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
253     xmlSecAssert2(buffer != NULL, -1);
254 
255     if(xmlSecBufferGetSize(buffer) == 0) {
256         xmlSecInvalidZeroKeyDataSizeError(xmlSecTransformGetName(transform));
257         return(-1);
258     }
259 
260     xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1);
261 
262     /* at this point we know what should be they key, go ahead with the CNG
263      * calls */
264 
265     status = BCryptOpenAlgorithmProvider(&ctx->hAlg,
266         ctx->pszAlgId,
267         NULL,
268         BCRYPT_ALG_HANDLE_HMAC_FLAG);
269     if(status != STATUS_SUCCESS) {
270         xmlSecMSCngNtError("BCryptOpenAlgorithmProvider",
271             xmlSecTransformGetName(transform), status);
272         return(-1);
273     }
274 
275     status = BCryptGetProperty(ctx->hAlg,
276         BCRYPT_HASH_LENGTH,
277         (PBYTE)&ctx->hashLength,
278         sizeof(ctx->hashLength),
279         &resultLength,
280         0);
281     if(status != STATUS_SUCCESS) {
282         xmlSecMSCngNtError("BCryptGetProperty",
283             xmlSecTransformGetName(transform), status);
284         return(-1);
285     }
286 
287     ctx->hash = (PBYTE)xmlMalloc(ctx->hashLength);
288     if(ctx->hash == NULL) {
289         xmlSecMallocError(ctx->hashLength, NULL);
290         return(-1);
291     }
292 
293     status = BCryptCreateHash(ctx->hAlg,
294         &ctx->hHash,
295         NULL,
296         0,
297         (PBYTE)xmlSecBufferGetData(buffer),
298         xmlSecBufferGetSize(buffer),
299         0);
300     if(status != STATUS_SUCCESS) {
301         xmlSecMSCngNtError("BCryptCreateHash",
302             xmlSecTransformGetName(transform), status);
303         return(-1);
304     }
305 
306     if (ctx->truncationLength == 0) {
307         /* no custom value is requested, then default to the full length */
308         ctx->truncationLength = ctx->hashLength * 8;
309     }
310 
311     ctx->initialized = 1;
312     return(0);
313 }
314 
315 static int
xmlSecMSCngHmacVerify(xmlSecTransformPtr transform,const xmlSecByte * data,xmlSecSize dataSize,xmlSecTransformCtxPtr transformCtx)316 xmlSecMSCngHmacVerify(xmlSecTransformPtr transform, const xmlSecByte* data,
317         xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx) {
318     xmlSecMSCngHmacCtxPtr ctx;
319     xmlSecSize truncationBytes;
320     static xmlSecByte lastByteMasks[] = { 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8,
321         0xFC, 0xFE };
322     xmlSecByte mask;
323 
324     xmlSecAssert2(xmlSecTransformIsValid(transform), -1);
325     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
326     xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1);
327     xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1);
328     xmlSecAssert2(data != NULL, -1);
329     xmlSecAssert2(dataSize > 0, -1);
330     xmlSecAssert2(transformCtx != NULL, -1);
331 
332     ctx = xmlSecMSCngHmacGetCtx(transform);
333     xmlSecAssert2(ctx != NULL, -1);
334     xmlSecAssert2(ctx->truncationLength > 0, -1);
335 
336     /* round up */
337     truncationBytes = (ctx->truncationLength + 7) / 8;
338 
339     /* compare the digest size in bytes */
340     if(dataSize != truncationBytes) {
341         xmlSecInvalidSizeError("HMAC digest",
342                                dataSize, truncationBytes,
343                                xmlSecTransformGetName(transform));
344         transform->status = xmlSecTransformStatusFail;
345         return(0);
346     }
347 
348     /* we check the last byte separately as possibly not all bits should be
349      * compared */
350     mask = lastByteMasks[ctx->truncationLength % 8];
351     if((ctx->hash[dataSize - 1] & mask) != (data[dataSize - 1]  & mask)) {
352         xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH,
353             xmlSecTransformGetName(transform),
354             "data and digest do not match (last byte)");
355         transform->status = xmlSecTransformStatusFail;
356         return(0);
357     }
358 
359     /* now check the rest of the digest */
360     if((dataSize > 1) && (memcmp(ctx->hash, data, dataSize - 1) != 0)) {
361         xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH,
362                          xmlSecTransformGetName(transform),
363                          "data and digest do not match");
364         transform->status = xmlSecTransformStatusFail;
365         return(0);
366     }
367 
368     transform->status = xmlSecTransformStatusOk;
369     return(0);
370 }
371 
372 static int
xmlSecMSCngHmacExecute(xmlSecTransformPtr transform,int last,xmlSecTransformCtxPtr transformCtx)373 xmlSecMSCngHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
374     xmlSecMSCngHmacCtxPtr ctx;
375     xmlSecBufferPtr in, out;
376     NTSTATUS status;
377     int ret;
378 
379     xmlSecAssert2(xmlSecTransformIsValid(transform), -1);
380     xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
381     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngHmacSize), -1);
382     xmlSecAssert2(transformCtx != NULL, -1);
383 
384     in = &(transform->inBuf);
385     out = &(transform->outBuf);
386 
387     ctx = xmlSecMSCngHmacGetCtx(transform);
388     xmlSecAssert2(ctx != NULL, -1);
389     xmlSecAssert2(ctx->initialized != 0, -1);
390 
391     if(transform->status == xmlSecTransformStatusNone) {
392         /* we should be already initialized when we set key */
393         transform->status = xmlSecTransformStatusWorking;
394     }
395 
396     if(transform->status == xmlSecTransformStatusWorking) {
397         xmlSecSize inSize;
398 
399         inSize = xmlSecBufferGetSize(in);
400         if(inSize > 0) {
401             status = BCryptHashData(ctx->hHash,
402                 xmlSecBufferGetData(in),
403                 inSize,
404                 0);
405             if(status != STATUS_SUCCESS) {
406                 xmlSecMSCngNtError("BCryptHashData",
407                     xmlSecTransformGetName(transform), status);
408                 return(-1);
409             }
410 
411             ret = xmlSecBufferRemoveHead(in, inSize);
412             if(ret < 0) {
413                 xmlSecInternalError2("xmlSecBufferRemoveHead",
414                     xmlSecTransformGetName(transform), "size=%d", inSize);
415                 return(-1);
416             }
417         }
418 
419         if(last) {
420             status = BCryptFinishHash(ctx->hHash,
421                 ctx->hash,
422                 ctx->hashLength,
423                 0);
424             if(status != STATUS_SUCCESS) {
425                 xmlSecMSCngNtError("BCryptFinishHash",
426                     xmlSecTransformGetName(transform), status);
427                 return(-1);
428             }
429 
430             /* copy result to output */
431             if(transform->operation == xmlSecTransformOperationSign) {
432                 /* round up */
433                 xmlSecSize truncationBytes = (ctx->truncationLength + 7) / 8;
434 
435                 ret = xmlSecBufferAppend(out, ctx->hash, truncationBytes);
436                 if(ret < 0) {
437                     xmlSecInternalError2("xmlSecBufferAppend",
438                                          xmlSecTransformGetName(transform),
439                                          "size=%d", truncationBytes);
440                     return(-1);
441                 }
442             }
443             transform->status = xmlSecTransformStatusFinished;
444         }
445     } else if(transform->status == xmlSecTransformStatusFinished) {
446         /* the only way we can get here is if there is no input */
447         xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
448     } else {
449         xmlSecInvalidTransfromStatusError(transform);
450         return(-1);
451     }
452 
453     return(0);
454 }
455 
456 #ifndef XMLSEC_NO_MD5
457 /******************************************************************************
458  *
459  * HMAC MD5
460  *
461  ******************************************************************************/
462 static xmlSecTransformKlass xmlSecMSCngHmacMd5Klass = {
463     /* klass/object sizes */
464     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
465     xmlSecMSCngHmacSize,                        /* xmlSecSize objSize */
466 
467     xmlSecNameHmacMd5,                          /* const xmlChar* name; */
468     xmlSecHrefHmacMd5,                          /* const xmlChar* href; */
469     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
470 
471     xmlSecMSCngHmacInitialize,                  /* xmlSecTransformInitializeMethod initialize; */
472     xmlSecMSCngHmacFinalize,                    /* xmlSecTransformFinalizeMethod finalize; */
473     xmlSecMSCngHmacNodeRead,                    /* xmlSecTransformNodeReadMethod readNode; */
474     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
475     xmlSecMSCngHmacSetKeyReq,                   /* xmlSecTransformSetKeyReqMethod setKeyReq; */
476     xmlSecMSCngHmacSetKey,                      /* xmlSecTransformSetKeyMethod setKey; */
477     xmlSecMSCngHmacVerify,                      /* xmlSecTransformValidateMethod validate; */
478     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
479     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
480     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
481     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
482     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
483     xmlSecMSCngHmacExecute,                     /* xmlSecTransformExecuteMethod execute; */
484 
485     NULL,                                       /* void* reserved0; */
486     NULL,                                       /* void* reserved1; */
487 };
488 
489 /**
490  * xmlSecMSCngTransformHmacMd5GetKlass:
491  *
492  * The HMAC-MD5 transform klass.
493  *
494  * Returns: the HMAC-MD5 transform klass.
495  */
496 xmlSecTransformId
xmlSecMSCngTransformHmacMd5GetKlass(void)497 xmlSecMSCngTransformHmacMd5GetKlass(void) {
498     return(&xmlSecMSCngHmacMd5Klass);
499 }
500 
501 #endif /* XMLSEC_NO_MD5 */
502 
503 #ifndef XMLSEC_NO_SHA1
504 /******************************************************************************
505  *
506  * HMAC SHA1
507  *
508  ******************************************************************************/
509 static xmlSecTransformKlass xmlSecMSCngHmacSha1Klass = {
510     /* klass/object sizes */
511     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
512     xmlSecMSCngHmacSize,                        /* xmlSecSize objSize */
513 
514     xmlSecNameHmacSha1,                         /* const xmlChar* name; */
515     xmlSecHrefHmacSha1,                         /* const xmlChar* href; */
516     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
517 
518     xmlSecMSCngHmacInitialize,                  /* xmlSecTransformInitializeMethod initialize; */
519     xmlSecMSCngHmacFinalize,                    /* xmlSecTransformFinalizeMethod finalize; */
520     xmlSecMSCngHmacNodeRead,                    /* xmlSecTransformNodeReadMethod readNode; */
521     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
522     xmlSecMSCngHmacSetKeyReq,                   /* xmlSecTransformSetKeyReqMethod setKeyReq; */
523     xmlSecMSCngHmacSetKey,                      /* xmlSecTransformSetKeyMethod setKey; */
524     xmlSecMSCngHmacVerify,                      /* xmlSecTransformValidateMethod validate; */
525     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
526     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
527     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
528     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
529     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
530     xmlSecMSCngHmacExecute,                     /* xmlSecTransformExecuteMethod execute; */
531 
532     NULL,                                       /* void* reserved0; */
533     NULL,                                       /* void* reserved1; */
534 };
535 
536 /**
537  * xmlSecMSCngTransformHmacSha1GetKlass:
538  *
539  * The HMAC-SHA1 transform klass.
540  *
541  * Returns: the HMAC-SHA1 transform klass.
542  */
543 xmlSecTransformId
xmlSecMSCngTransformHmacSha1GetKlass(void)544 xmlSecMSCngTransformHmacSha1GetKlass(void) {
545     return(&xmlSecMSCngHmacSha1Klass);
546 }
547 
548 #endif /* XMLSEC_NO_SHA1 */
549 
550 #ifndef XMLSEC_NO_SHA256
551 /******************************************************************************
552  *
553  * HMAC SHA256
554  *
555  ******************************************************************************/
556 static xmlSecTransformKlass xmlSecMSCngHmacSha256Klass = {
557     /* klass/object sizes */
558     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
559     xmlSecMSCngHmacSize,                        /* xmlSecSize objSize */
560 
561     xmlSecNameHmacSha256,                       /* const xmlChar* name; */
562     xmlSecHrefHmacSha256,                       /* const xmlChar* href; */
563     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
564 
565     xmlSecMSCngHmacInitialize,                  /* xmlSecTransformInitializeMethod initialize; */
566     xmlSecMSCngHmacFinalize,                    /* xmlSecTransformFinalizeMethod finalize; */
567     xmlSecMSCngHmacNodeRead,                    /* xmlSecTransformNodeReadMethod readNode; */
568     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
569     xmlSecMSCngHmacSetKeyReq,                   /* xmlSecTransformSetKeyReqMethod setKeyReq; */
570     xmlSecMSCngHmacSetKey,                      /* xmlSecTransformSetKeyMethod setKey; */
571     xmlSecMSCngHmacVerify,                      /* xmlSecTransformValidateMethod validate; */
572     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
573     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
574     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
575     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
576     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
577     xmlSecMSCngHmacExecute,                     /* xmlSecTransformExecuteMethod execute; */
578 
579     NULL,                                       /* void* reserved0; */
580     NULL,                                       /* void* reserved1; */
581 };
582 
583 /**
584  * xmlSecMSCngTransformHmacSha256GetKlass:
585  *
586  * The HMAC-SHA256 transform klass.
587  *
588  * Returns: the HMAC-SHA256 transform klass.
589  */
590 xmlSecTransformId
xmlSecMSCngTransformHmacSha256GetKlass(void)591 xmlSecMSCngTransformHmacSha256GetKlass(void) {
592     return(&xmlSecMSCngHmacSha256Klass);
593 }
594 
595 #endif /* XMLSEC_NO_SHA256 */
596 
597 #ifndef XMLSEC_NO_SHA384
598 /******************************************************************************
599  *
600  * HMAC SHA384
601  *
602  ******************************************************************************/
603 static xmlSecTransformKlass xmlSecMSCngHmacSha384Klass = {
604     /* klass/object sizes */
605     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
606     xmlSecMSCngHmacSize,                        /* xmlSecSize objSize */
607 
608     xmlSecNameHmacSha384,                       /* const xmlChar* name; */
609     xmlSecHrefHmacSha384,                       /* const xmlChar* href; */
610     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
611 
612     xmlSecMSCngHmacInitialize,                  /* xmlSecTransformInitializeMethod initialize; */
613     xmlSecMSCngHmacFinalize,                    /* xmlSecTransformFinalizeMethod finalize; */
614     xmlSecMSCngHmacNodeRead,                    /* xmlSecTransformNodeReadMethod readNode; */
615     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
616     xmlSecMSCngHmacSetKeyReq,                   /* xmlSecTransformSetKeyReqMethod setKeyReq; */
617     xmlSecMSCngHmacSetKey,                      /* xmlSecTransformSetKeyMethod setKey; */
618     xmlSecMSCngHmacVerify,                      /* xmlSecTransformValidateMethod validate; */
619     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
620     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
621     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
622     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
623     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
624     xmlSecMSCngHmacExecute,                     /* xmlSecTransformExecuteMethod execute; */
625 
626     NULL,                                       /* void* reserved0; */
627     NULL,                                       /* void* reserved1; */
628 };
629 
630 /**
631  * xmlSecMSCngTransformHmacSha384GetKlass:
632  *
633  * The HMAC-SHA384 transform klass.
634  *
635  * Returns: the HMAC-SHA384 transform klass.
636  */
637 xmlSecTransformId
xmlSecMSCngTransformHmacSha384GetKlass(void)638 xmlSecMSCngTransformHmacSha384GetKlass(void) {
639     return(&xmlSecMSCngHmacSha384Klass);
640 }
641 
642 #endif /* XMLSEC_NO_SHA384 */
643 
644 #ifndef XMLSEC_NO_SHA512
645 /******************************************************************************
646  *
647  * HMAC SHA512
648  *
649  ******************************************************************************/
650 static xmlSecTransformKlass xmlSecMSCngHmacSha512Klass = {
651     /* klass/object sizes */
652     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
653     xmlSecMSCngHmacSize,                        /* xmlSecSize objSize */
654 
655     xmlSecNameHmacSha512,                       /* const xmlChar* name; */
656     xmlSecHrefHmacSha512,                       /* const xmlChar* href; */
657     xmlSecTransformUsageSignatureMethod,        /* xmlSecTransformUsage usage; */
658 
659     xmlSecMSCngHmacInitialize,                  /* xmlSecTransformInitializeMethod initialize; */
660     xmlSecMSCngHmacFinalize,                    /* xmlSecTransformFinalizeMethod finalize; */
661     xmlSecMSCngHmacNodeRead,                    /* xmlSecTransformNodeReadMethod readNode; */
662     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
663     xmlSecMSCngHmacSetKeyReq,                   /* xmlSecTransformSetKeyReqMethod setKeyReq; */
664     xmlSecMSCngHmacSetKey,                      /* xmlSecTransformSetKeyMethod setKey; */
665     xmlSecMSCngHmacVerify,                      /* xmlSecTransformValidateMethod validate; */
666     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
667     xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
668     xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
669     NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
670     NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
671     xmlSecMSCngHmacExecute,                     /* xmlSecTransformExecuteMethod execute; */
672 
673     NULL,                                       /* void* reserved0; */
674     NULL,                                       /* void* reserved1; */
675 };
676 
677 /**
678  * xmlSecMSCngTransformHmacSha512GetKlass:
679  *
680  * The HMAC-SHA512 transform klass.
681  *
682  * Returns: the HMAC-SHA512 transform klass.
683  */
684 xmlSecTransformId
xmlSecMSCngTransformHmacSha512GetKlass(void)685 xmlSecMSCngTransformHmacSha512GetKlass(void) {
686     return(&xmlSecMSCngHmacSha512Klass);
687 }
688 
689 #endif /* XMLSEC_NO_SHA512 */
690 
691 #endif /* XMLSEC_NO_HMAC */
692