ReactOS 0.4.17-dev-1005-g171e1de
lms.c
Go to the documentation of this file.
1//
2// lms.c LMS implementation
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7#include "precomp.h"
8
9//
10// See the symcrypt.h file for documentation on what the various functions do.
11//
15};
16
18{
20
21 // output length
23
24 // total tree height
26
27 // hash function index
29
31
33
34
36
37 // algId m h HIdx
38 { SYMCRYPT_LMS_SHA256_M32_H5, 32, 5 , 0 },
39 { SYMCRYPT_LMS_SHA256_M32_H10, 32, 10, 0 },
40 { SYMCRYPT_LMS_SHA256_M32_H15, 32, 15, 0 },
41 { SYMCRYPT_LMS_SHA256_M32_H20, 32, 20, 0 },
42 { SYMCRYPT_LMS_SHA256_M32_H25, 32, 25, 0 },
43 { SYMCRYPT_LMS_SHAKE_M32_H5, 32, 5 , 1 },
44 { SYMCRYPT_LMS_SHAKE_M32_H10, 32, 10, 1 },
45 { SYMCRYPT_LMS_SHAKE_M32_H15, 32, 15, 1 },
46 { SYMCRYPT_LMS_SHAKE_M32_H20, 32, 20, 1 },
47 { SYMCRYPT_LMS_SHAKE_M32_H25, 32, 25, 1 },
48 { SYMCRYPT_LMS_SHA256_M24_H5, 24, 5 , 0 },
49 { SYMCRYPT_LMS_SHA256_M24_H10, 24, 10, 0 },
50 { SYMCRYPT_LMS_SHA256_M24_H15, 24, 15, 0 },
51 { SYMCRYPT_LMS_SHA256_M24_H20, 24, 20, 0 },
52 { SYMCRYPT_LMS_SHA256_M24_H25, 24, 25, 0 },
53 { SYMCRYPT_LMS_SHAKE_M24_H5, 24, 5 , 1 },
54 { SYMCRYPT_LMS_SHAKE_M24_H10, 24, 10, 1 },
55 { SYMCRYPT_LMS_SHAKE_M24_H15, 24, 15, 1 },
56 { SYMCRYPT_LMS_SHAKE_M24_H20, 24, 20, 1 },
57 { SYMCRYPT_LMS_SHAKE_M24_H25, 24, 25, 1 },
58};
59
61{
63
64 // output length
66
67 // Winternitz width
69
70 // hash function index
72
75
77
78 // algId n w HIdx
95};
96static const BYTE SYMCRYPT_LMS_D_PBLC[] = { 0x80, 0x80 };
97static const BYTE SYMCRYPT_LMS_D_MESG[] = { 0x81, 0x81 };
98static const BYTE SYMCRYPT_LMS_D_LEAF[] = { 0x82, 0x82 };
99static const BYTE SYMCRYPT_LMS_D_INTR[] = { 0x83, 0x83 };
100
101static
102VOID
104 _In_ PCSYMCRYPT_HASH pHash,
106 _In_reads_bytes_(sizeof(UINT32)) PCBYTE pbLeafNumber,
107 _In_reads_bytes_(cbRandomizer) PCBYTE pbRandomizer,
108 SIZE_T cbRandomizer,
109 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
110 SIZE_T cbMessage,
111 _Out_writes_bytes_(cbOut) PBYTE pbOut,
112 SIZE_T cbOut)
113{
115
116 SymCryptHashInit(pHash, &state);
118 SymCryptHashAppend(pHash, &state, pbLeafNumber, sizeof(UINT32));
120 SymCryptHashAppend(pHash, &state, pbRandomizer, cbRandomizer);
121 SymCryptHashAppend(pHash, &state, pbMessage, cbMessage);
122 SymCryptHashResult(pHash, &state, pbOut, cbOut);
123}
124
125static
126VOID
130 _In_ UINT32 nLeafNumber,
131 _In_ UINT32 nPIdx,
132 _Out_writes_bytes_(pKey->params.cbHashOutput)
133 PBYTE pbOtsPrivateKey)
134{
135 UINT32 cbHashOutput = pKey->params.cbHashOutput;
136 PCSYMCRYPT_HASH pHash = pKey->params.pLmsHashFunction;
138 BYTE abTemp[sizeof(UINT32) + 3] = { 0 }; // sizeof(UINT32) for nLeafNumber, 2 bytes of nPIdx and 1 byte of 0xff
139
140 SYMCRYPT_ASSERT(nLeafNumber <= (((UINT32)1 << pKey->params.nTreeHeight) - 1));
141
142 SYMCRYPT_STORE_MSBFIRST32(abTemp, nLeafNumber);
143 SYMCRYPT_STORE_MSBFIRST16(abTemp + sizeof(UINT32), (UINT16)nPIdx);
144 abTemp[sizeof(UINT32) + 2] = 0xff;
145
146 SymCryptHashInit(pHash, &state);
148 SymCryptHashAppend(pHash, &state, abTemp, sizeof(abTemp));
149 SymCryptHashAppend(pHash, &state, pKey->abSeed, cbHashOutput);
150 SymCryptHashResult(pHash, &state, pbOtsPrivateKey, cbHashOutput);
151}
152
153static
154VOID
158{
160
161 SymCryptWipeKnownSize(pKey->abSeed, sizeof(pKey->abSeed));
162 SymCryptWipeKnownSize(pKey->abPublicRoot, sizeof(pKey->abPublicRoot));
163 SymCryptWipeKnownSize(pKey->abId, sizeof(pKey->abId));
164 pKey->nNextUnusedLeaf = 0;
166}
167
168static
169UINT16
171 _In_reads_bytes_(cbString) PCBYTE pbString,
172 UINT32 cbString,
173 UINT32 nWidth,
174 UINT32 nLeftShift)
175{
176 UINT32 sum = 0;
177 UINT32 max = (1 << nWidth) - 1;
179
180 for (UINT32 i = 0; i < (cbString * 8 / nWidth); i = i + 1)
181 {
182 sum = sum + max - SymCryptHbsGetDigit(nWidth, pbString, cbString, i);
183 }
184 return (UINT16)(sum << nLeftShift);
185}
186
187static
188SIZE_T
192{
193 UINT32 n = pParams->cbHashOutput;
194 UINT32 p = pParams->nByteStringCount;
195 SIZE_T size = 0;
196
197 size += sizeof(UINT32); // type
198 size += n; // randomizer
199 size += p * n; // y[0..p-1]
200
201 return size;
202}
203
204static
205VOID
209 UINT64 nLeafNumber,
210 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
211 SIZE_T cbMessage,
212 _In_reads_bytes_(pKey->params.cbHashOutput) PCBYTE pbRandomizer,
213 _Out_writes_bytes_(cbSignature) PBYTE pbSignature,
214 SIZE_T cbSignature)
215{
216 PCSYMCRYPT_HASH pHash = pKey->params.pLmsHashFunction;
218 UINT32 nIndex = 0;
219 UINT32 cbHashOutput = pKey->params.cbHashOutput;
220 UINT32 nWinternitzChainWidth = pKey->params.nWinternitzChainWidth;
221 SIZE_T cbRemainingBytes = cbSignature;
222 UINT16 nChecksum = 0;
223 BYTE en32LeafNumber[sizeof(UINT32)] = {0};
224 BYTE en16Index[sizeof(UINT16)] = { 0 };
225 BYTE abOtsPrivateKey[SYMCRYPT_LMS_MAX_N] = { 0 };
226 BYTE abLmsHashedMessage[SYMCRYPT_LMS_MAX_N + sizeof(nChecksum)] = { 0 };
227 PBYTE pbDest = pbSignature;
228
229 SYMCRYPT_ASSERT(cbSignature == LmsOtsSizeofSignatureFromParams(&pKey->params));
230
231 SYMCRYPT_STORE_MSBFIRST32(pbDest, pKey->params.lmsOtsAlgID);
232 pbDest += sizeof(UINT32);
233 cbRemainingBytes -= sizeof(UINT32);
234
235 memcpy(pbDest, pbRandomizer, cbHashOutput);
236 pbDest += cbHashOutput;
237 cbRemainingBytes -= cbHashOutput;
238
239 SYMCRYPT_STORE_MSBFIRST32(en32LeafNumber, (UINT32)nLeafNumber);
240 LmsHashMessage(pHash, pKey->abId, en32LeafNumber, pbRandomizer, cbHashOutput, pbMessage, cbMessage, abLmsHashedMessage, cbHashOutput);
241
242 nChecksum = LmsOtsCalculateChecksum(abLmsHashedMessage, cbHashOutput, nWinternitzChainWidth, pKey->params.nChecksumLShiftBits);
243 SYMCRYPT_STORE_MSBFIRST16((UINT16*)&abLmsHashedMessage[cbHashOutput], nChecksum);
244
245 SymCryptHashInit(pHash, &state);
246 for (nIndex = 0; nIndex < pKey->params.nByteStringCount; nIndex++)
247 {
248 BYTE coeff = (BYTE)SymCryptHbsGetDigit(nWinternitzChainWidth, abLmsHashedMessage, cbHashOutput + sizeof(nChecksum), nIndex);
249 LmsOtskeyComputePrivate(pKey, (UINT32)nLeafNumber, nIndex, abOtsPrivateKey);
250
251 SYMCRYPT_STORE_MSBFIRST16(en16Index, (UINT16)nIndex);
252
253 for (BYTE j = 0; j < coeff; j++)
254 {
256 SymCryptHashAppend(pHash, &state, en32LeafNumber, sizeof(UINT32));
257 SymCryptHashAppend(pHash, &state, en16Index, sizeof(UINT16));
258 SymCryptHashAppend(pHash, &state, &j, 1);
259 SymCryptHashAppend(pHash, &state, abOtsPrivateKey, cbHashOutput);
260 SymCryptHashResult(pHash, &state, abOtsPrivateKey, cbHashOutput);
261 }
262 memcpy(pbDest, abOtsPrivateKey, cbHashOutput);
263 pbDest += cbHashOutput;
264 cbRemainingBytes -= cbHashOutput;
265 }
266 SYMCRYPT_ASSERT(cbRemainingBytes == 0);
267
268 return;
269}
270
271static
272VOID
276 UINT32 nNodeIdx,
277 _Out_writes_bytes_(pKey->params.cbHashOutput) PBYTE pbK)
278{
279 UINT32 cbHashOutput = pKey->params.cbHashOutput;
280 UINT32 maxJ = (1 << pKey->params.nWinternitzChainWidth) - 1;
281 PCSYMCRYPT_HASH pHash = pKey->params.pLmsHashFunction;
282 SYMCRYPT_HASH_STATE statePriv = { 0 };
283 SYMCRYPT_HASH_STATE statePub = { 0 };
284 BYTE en32LeafNumber[sizeof(UINT32)] = { 0 };
285 BYTE en16Index[sizeof(UINT16)] = { 0 };
286 BYTE abNode[SYMCRYPT_LMS_MAX_N] = { 0 };
287
288 SYMCRYPT_STORE_MSBFIRST32(en32LeafNumber, nNodeIdx);
289
290 SymCryptHashInit(pHash, &statePub);
292 SymCryptHashAppend(pHash, &statePub, en32LeafNumber, sizeof(UINT32));
294
295 SymCryptHashInit(pHash, &statePriv);
296 for (UINT32 i = 0; i < pKey->params.nByteStringCount; i++)
297 {
298 LmsOtskeyComputePrivate(pKey, nNodeIdx, i, abNode);
300
301 for (BYTE j = 0; j < maxJ; j++)
302 {
304 SymCryptHashAppend(pHash, &statePriv, en32LeafNumber, sizeof(UINT32));
305 SymCryptHashAppend(pHash, &statePriv, en16Index, sizeof(UINT16));
306 SymCryptHashAppend(pHash, &statePriv, &j, 1);
307 SymCryptHashAppend(pHash, &statePriv, abNode, cbHashOutput);
308 SymCryptHashResult(pHash, &statePriv, abNode, cbHashOutput);
309 }
310 SymCryptHashAppend(pHash, &statePub, abNode, cbHashOutput);
311 }
312 SymCryptHashResult(pHash, &statePub, pbK, cbHashOutput);
313}
314
315static
316VOID
320 UINT32 nIndex,
321 _Out_writes_bytes_(pKey->params.cbHashOutput) PBYTE pbNodeValue,
322 SIZE_T cbNodeValue)
323{
324 UNREFERENCED_PARAMETER(cbNodeValue);
325
326 UINT32 cbHashOutput = pKey->params.cbHashOutput;
327 UINT32 nInternalNodes = (UINT32)1 << pKey->params.nTreeHeight;
328 PCSYMCRYPT_HASH pHash = pKey->params.pLmsHashFunction;
330 BYTE abTemp[SYMCRYPT_LMS_MAX_N] = { 0 };
331 BYTE en32Index[sizeof(UINT32)] = { 0 };
332 BYTE abOtsPubKey[SYMCRYPT_LMS_MAX_N] = { 0 };
333
334 SYMCRYPT_ASSERT(nIndex > 0);
335 SYMCRYPT_ASSERT(cbNodeValue == cbHashOutput);
336
337 SYMCRYPT_STORE_MSBFIRST32(en32Index, nIndex);
338
339 SymCryptHashInit(pHash, &state);
341 SymCryptHashAppend(pHash, &state, en32Index, sizeof(UINT32));
342 if (nIndex >= nInternalNodes)
343 {
344 LmsOtskeyComputePublic(pKey, nIndex - nInternalNodes, abOtsPubKey);
345
347 SymCryptHashAppend(pHash, &state, abOtsPubKey, cbHashOutput);
348 }
349 else
350 {
352
353 LmsComputeNodeValue(pKey, 2 * nIndex, abTemp, cbHashOutput);
354 SymCryptHashAppend(pHash, &state, abTemp, cbHashOutput);
356
357 LmsComputeNodeValue(pKey, 2 * nIndex + 1, abTemp, cbHashOutput);
358 SymCryptHashAppend(pHash, &state, abTemp, cbHashOutput);
359 }
360 SymCryptHashResult(pHash, &state, pbNodeValue, cbHashOutput);
361}
362
366 SYMCRYPT_LMS_ALGID lmsAlgID,
369{
370 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
371 SIZE_T uLmsParametersCount = 0;
372 SIZE_T uLmsOtsParametersCount = 0;
373 UINT32 u = 0;
374 UINT32 v = 0;
377 BOOL bFound = FALSE;
378
379 SymCryptWipeKnownSize(pParams, sizeof(*pParams));
380 pLmsOtsParameters = LmsOtsParametersPredefined;
381 uLmsOtsParametersCount = SYMCRYPT_ARRAY_SIZE(LmsOtsParametersPredefined);
382 pLmsParameters = LmsParametersPredefined;
383 uLmsParametersCount = SYMCRYPT_ARRAY_SIZE(LmsParametersPredefined);
384
385 for (UINT32 i = 0; i < uLmsParametersCount; i++)
386 {
387 if (pLmsParameters[i].lmsAlgId == lmsAlgID)
388 {
389 pParams->lmsAlgID = lmsAlgID;
390 pParams->nTreeHeight = pLmsParameters[i].nTreeHeight;
392
393 pParams->cbHashOutput = pLmsParameters[i].cbHashOutput;
394
395 SYMCRYPT_ASSERT(pLmsParameters[i].nHashIdx < SYMCRYPT_ARRAY_SIZE(LmsHashObjects));
396 pParams->pLmsHashFunction = *LmsHashObjects[pLmsParameters[i].nHashIdx];
397 bFound = TRUE;
398 break;
399 }
400 }
401 if (!bFound)
402 {
403 scError = SYMCRYPT_INVALID_ARGUMENT;
404 goto cleanup;
405 }
406
407 bFound = FALSE;
408 for (UINT32 i = 0; i < uLmsOtsParametersCount; i++)
409 {
410 if (pLmsOtsParameters[i].lmsOtsAlgId == lmsOtsAlgID)
411 {
412 SYMCRYPT_ASSERT(pLmsOtsParameters[i].nHashIdx < SYMCRYPT_ARRAY_SIZE(LmsHashObjects));
413
414 if (pParams->pLmsHashFunction != *LmsHashObjects[pLmsOtsParameters[i].nHashIdx] ||
415 pParams->cbHashOutput != pLmsOtsParameters[i].cbHashOutput)
416 {
417 scError = SYMCRYPT_INVALID_ARGUMENT;
418 goto cleanup;
419 }
420 pParams->lmsOtsAlgID = lmsOtsAlgID;
421 pParams->nWinternitzChainWidth = pLmsOtsParameters[i].nWidth;
423 pParams->cbHashOutput,
424 pParams->nWinternitzChainWidth,
425 &u,
426 &v);
427 SYMCRYPT_ASSERT((v * pParams->nWinternitzChainWidth) <= SYMCRYPT_LMS_CHECKSUM_SIZE);
428 pParams->nChecksumLShiftBits = SYMCRYPT_LMS_CHECKSUM_SIZE - (v * pParams->nWinternitzChainWidth);
429 pParams->nByteStringCount = u + v;
430 bFound = TRUE;
431 break;
432 }
433 }
434 if (!bFound)
435 {
436 scError = SYMCRYPT_INVALID_ARGUMENT;
437 goto cleanup;
438 }
439
440cleanup:
441 return scError;
442}
443
444SIZE_T
448{
449 SIZE_T size = 0;
450
451 size += sizeof(UINT32); // q
452 size += LmsOtsSizeofSignatureFromParams(pParams); // LMS-OTS signature
453 size += sizeof(UINT32); // type
454 size += pParams->nTreeHeight * pParams->cbHashOutput; // path[0..h-1]
455 return size;
456}
457
462 UINT32 lmsAlgID,
468{
469 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
470 UINT32 u = 0;
471 UINT32 v = 0;
472
473 SymCryptWipeKnownSize(pParams, sizeof(*pParams));
474
475 // nTreeHeight must be positive and maximum SYMCRYPT_LMS_MAX_CUSTOM_TREE_HEIGHT
477 {
478 scError = SYMCRYPT_INVALID_ARGUMENT;
479 goto cleanup;
480 }
481
482 // Output cbHashOutput cannot be larger than the hash output size or SYMCRYPT_LMS_MAX_N
484 {
485 scError = SYMCRYPT_INVALID_ARGUMENT;
486 goto cleanup;
487 }
488
489 // Winternitz parameter must be one of 1, 2, 4, or 8
491 {
492 scError = SYMCRYPT_INVALID_ARGUMENT;
493 goto cleanup;
494 }
495
496 pParams->lmsAlgID = lmsAlgID;
497 pParams->lmsOtsAlgID = lmsOtsAlgID;
498 pParams->pLmsHashFunction = pLmsHashFunction;
499 pParams->nTreeHeight = nTreeHeight;
500 pParams->cbHashOutput = cbHashOutput;
501 pParams->nWinternitzChainWidth = nWinternitzChainWidth;
503 pParams->cbHashOutput,
504 pParams->nWinternitzChainWidth,
505 &u,
506 &v);
507 pParams->nChecksumLShiftBits = SYMCRYPT_LMS_CHECKSUM_SIZE - (v * pParams->nWinternitzChainWidth);
508 pParams->nByteStringCount = u + v;
509
510cleanup:
511 return scError;
512}
513
519 _Out_ SIZE_T* pcbKey)
520{
521 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
522
523 switch (keyType)
524 {
526 *pcbKey = SYMCRYPT_LMS_PUB_KEY_SIZE(pParams->cbHashOutput);
527 break;
528
530 *pcbKey = SYMCRYPT_LMS_PRIV_KEY_SIZE(pParams->cbHashOutput);
531 break;
532
533 default:
534 scError = SYMCRYPT_INVALID_ARGUMENT;
535 break;
536 }
537
538 return scError;
539}
540
546{
549
550 if (flags != 0)
551 {
552 goto cleanup;
553 }
554
556 if (pKey == NULL)
557 {
558 goto cleanup;
559 }
560
562 pKey->cbSize = cbSize;
563
564 memcpy(&pKey->params, pParams, sizeof(*pParams));
566
567cleanup:
568 return pKey;
569}
570
571VOID
575{
577
580}
581
582static
587{
589 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
590
592
593 // key to be verified has to be a private key
594 if (pKey->keyType != SYMCRYPT_LMSKEY_TYPE_PRIVATE)
595 {
596 scError = SYMCRYPT_INVALID_ARGUMENT;
597 goto cleanup;
598 }
599
600 // compute the public root from the private key, root node has index 1
602 pKey,
603 1,
605 pKey->params.cbHashOutput);
606
607 if (!SymCryptEqual(abPublicRoot, pKey->abPublicRoot, pKey->params.cbHashOutput))
608 {
609 scError = SYMCRYPT_HBS_PUBLIC_ROOT_MISMATCH;
610 }
611
612cleanup:
613
614 return scError;
615}
616
622{
623 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
624
626
627 if (flags != 0)
628 {
629 scError = SYMCRYPT_INVALID_ARGUMENT;
630 goto cleanup;
631 }
632
633 pKey->nNextUnusedLeaf = 0;
634 // Set the LMS key identifier I
636 if (scError != SYMCRYPT_NO_ERROR)
637 {
638 goto cleanup;
639 }
640
641 // Set the private key Seed value
642 scError = SymCryptCallbackRandom(pKey->abSeed, pKey->params.cbHashOutput);
643 if (scError != SYMCRYPT_NO_ERROR)
644 {
645 goto cleanup;
646 }
647
648 // compute the public root from the private key
650 pKey,
651 1,
652 pKey->abPublicRoot,
653 pKey->params.cbHashOutput);
654
656
657cleanup:
658 if (scError != SYMCRYPT_NO_ERROR)
659 {
661 }
662 return scError;
663}
664
671 _Out_writes_bytes_(cbBlob) PBYTE pbBlob,
672 SIZE_T cbBlob)
673{
674 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
675 SIZE_T cbHashOutput = pKey->params.cbHashOutput;
676 SIZE_T cbKey = 0;
677
679
680 if (flags != 0 ||
683 {
684 scError = SYMCRYPT_INVALID_ARGUMENT;
685 goto cleanup;
686 }
687
689 {
690 scError = SYMCRYPT_INVALID_ARGUMENT;
691 goto cleanup;
692 }
693
695 if (cbBlob != cbKey)
696 {
697 scError = SYMCRYPT_INVALID_ARGUMENT;
698 goto cleanup;
699 }
700 SYMCRYPT_STORE_MSBFIRST32(pbBlob, (UINT32)pKey->params.lmsAlgID);
701 pbBlob += sizeof(UINT32);
702
703 SYMCRYPT_STORE_MSBFIRST32(pbBlob, (UINT32)pKey->params.lmsOtsAlgID);
704 pbBlob += sizeof(UINT32);
705
708
709 memcpy(pbBlob, pKey->abPublicRoot, cbHashOutput);
710 pbBlob += cbHashOutput;
711
713 {
714
715 SYMCRYPT_ASSERT((pKey->nNextUnusedLeaf & 0xFFFFFFFF00000000) == 0);
716
717 SYMCRYPT_STORE_MSBFIRST32(pbBlob, (UINT32)pKey->nNextUnusedLeaf);
718 pbBlob += sizeof(UINT32);
719
720 memcpy(pbBlob, pKey->abSeed, cbHashOutput);
721 }
722
723cleanup:
724 return scError;
725}
726
730 _In_reads_bytes_(cbBlob) PCBYTE pbBlob,
731 SIZE_T cbBlob,
735{
736 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
737 UINT32 lmsAlgID = 0;
739 SIZE_T cbKey = 0;
740
742
744
746 {
747 scError = SYMCRYPT_INVALID_ARGUMENT;
748 goto cleanup;
749 }
750
751 // Public key validation can only be performed for private keys
754 {
755 scError = SYMCRYPT_INVALID_ARGUMENT;
756 goto cleanup;
757 }
758
760 if (cbBlob != cbKey)
761 {
762 scError = SYMCRYPT_INVALID_ARGUMENT;
763 goto cleanup;
764 }
765
766 lmsAlgID = SYMCRYPT_LOAD_MSBFIRST32(pbBlob);
767 pbBlob += sizeof(UINT32);
768
770 pbBlob += sizeof(UINT32);
771
772 // check if the lmsAlgID and lmsOtsAlgID matches the ones in the key
773 if (lmsAlgID != pKey->params.lmsAlgID || lmsOtsAlgID != pKey->params.lmsOtsAlgID)
774 {
775 scError = SYMCRYPT_INVALID_BLOB;
776 goto cleanup;
777 }
778 SymCryptWipeKnownSize(pKey->abPublicRoot, sizeof(pKey->abPublicRoot));
779 SymCryptWipeKnownSize(pKey->abId, sizeof(pKey->abId));
780
781 pKey->keyType = keyType;
782
785
786 memcpy(pKey->abPublicRoot, pbBlob, pKey->params.cbHashOutput);
787 pbBlob += pKey->params.cbHashOutput;
788
790 {
791 // Wipe private key material
792 pKey->nNextUnusedLeaf = 0;
793 SymCryptWipeKnownSize(pKey->abSeed, sizeof(pKey->abSeed));
794
795 pKey->nNextUnusedLeaf = SYMCRYPT_LOAD_MSBFIRST32(pbBlob);
796 pbBlob += sizeof(UINT32);
797
798 memcpy(pKey->abSeed, pbBlob,pKey->params.cbHashOutput);
799
801 {
803 if (scError != SYMCRYPT_NO_ERROR)
804 {
805 goto cleanup;
806 }
807 }
808 }
809
810cleanup:
811 if (scError != SYMCRYPT_NO_ERROR)
812 {
814 }
815
816 return scError;
817}
818
823 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
824 SIZE_T cbMessage,
826 _Out_writes_bytes_(cbSignature) PBYTE pbSignature,
827 SIZE_T cbSignature)
828{
829 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
830 UINT32 nLeafNumber = (UINT32)pKey->nNextUnusedLeaf;
831 UINT32 cbHashOutput = pKey->params.cbHashOutput;
832 UINT32 nTreeHeight = pKey->params.nTreeHeight;
833 SIZE_T cbRemainingBytes = cbSignature;
834 UINT32 nLeavesCount = ((UINT32)1 << nTreeHeight);
835 UINT32 nNodeIndex = 0;
836 UINT32 nTemp = 0;
837 SIZE_T cbOtsSignature = LmsOtsSizeofSignatureFromParams(&pKey->params);
838 BYTE abLMSRandomizer[SYMCRYPT_LMS_MAX_N] = { 0 };
839
841
842 if (flags != 0)
843 {
844 scError = SYMCRYPT_INVALID_ARGUMENT;
845 goto cleanup;
846 }
847
848 if (pKey->keyType != SYMCRYPT_LMSKEY_TYPE_PRIVATE)
849 {
850 scError = SYMCRYPT_INVALID_ARGUMENT;
851 goto cleanup;
852 }
853
854 if (cbSignature != SymCryptLmsSizeofSignatureFromParams(&pKey->params))
855 {
856 scError = SYMCRYPT_INVALID_ARGUMENT;
857 goto cleanup;
858 }
859
860 scError = SymCryptCallbackRandom(abLMSRandomizer, cbHashOutput);
861 if (scError != SYMCRYPT_NO_ERROR)
862 {
863 goto cleanup;
864 }
865
866 nLeafNumber = (UINT32)SYMCRYPT_ATOMIC_ADD64_POST_RELAXED(&pKey->nNextUnusedLeaf, 1) - 1;
867 if (nLeafNumber >= (nLeavesCount))
868 {
869 scError = SYMCRYPT_HBS_NO_OTS_KEYS_LEFT;
870 pKey->nNextUnusedLeaf = nLeavesCount;
871 goto cleanup;
872 }
873 SYMCRYPT_STORE_MSBFIRST32(pbSignature, nLeafNumber);
874 pbSignature += sizeof(UINT32);
875 cbRemainingBytes -= sizeof(UINT32);
876
878 pKey,
879 nLeafNumber,
880 pbMessage,
881 cbMessage,
882 abLMSRandomizer,
883 pbSignature,
884 cbOtsSignature);
885 pbSignature += cbOtsSignature;
886 cbRemainingBytes -= cbOtsSignature;
887
888 SYMCRYPT_STORE_MSBFIRST32(pbSignature, pKey->params.lmsAlgID);
889 pbSignature += sizeof(UINT32);
890 cbRemainingBytes -= sizeof(UINT32);
891
892 nNodeIndex = nLeavesCount + nLeafNumber;
893 // write the path into the signature
894 for (UINT32 nIndex = 0; nIndex < nTreeHeight; nIndex++)
895 {
896 nTemp = (nNodeIndex >> nIndex) ^ 1;
898 pKey,
899 nTemp,
900 pbSignature,
902 pbSignature += cbHashOutput;
903 cbRemainingBytes -= cbHashOutput;
904 }
905 SYMCRYPT_ASSERT(cbRemainingBytes == 0);
906
907cleanup:
908 return scError;
909}
910
911static
915 UINT32 nLeafNumber,
916 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
917 SIZE_T cbMessage,
918 _In_reads_bytes_(cbOtsSignature) PCBYTE pbOtsSignature,
919 SIZE_T cbOtsSignature,
921 _In_ PCSYMCRYPT_LMS_PARAMS pSigParams,
922 _Out_writes_bytes_(pSigParams->cbHashOutput) PBYTE pbOtsPubKeyCandidate)
923{
924 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
925 UINT32 cbHashOutput = pSigParams->cbHashOutput;
926 UINT32 nWinternitzChainWidth = pSigParams->nWinternitzChainWidth;
927 UINT32 nByteStringCount = pSigParams->nByteStringCount;
928 UINT32 nSigType = 0;
929 UINT32 nMaxJ = (1 << nWinternitzChainWidth) - 1;
930 UINT16 nCksm = 0;
931 PCSYMCRYPT_HASH pHash = pSigParams->pLmsHashFunction;
933 SYMCRYPT_HASH_STATE stateKc = { 0 };
934 BYTE en32LeafNumber[sizeof(UINT32)] = { 0 };
935 BYTE en16Index[sizeof(UINT16)] = { 0 };
936 BYTE abLmsHashedMsg[SYMCRYPT_LMS_MAX_N + sizeof(nCksm)] = { 0 };
937 BYTE abTmpRes[SYMCRYPT_LMS_MAX_N] = { 0 };
938 PCBYTE pbRandomizer = NULL;
939
940 if (cbOtsSignature != LmsOtsSizeofSignatureFromParams(pSigParams))
941 {
942 scError = SYMCRYPT_INVALID_ARGUMENT;
943 goto cleanup;
944 }
945
946 nSigType = SYMCRYPT_LOAD_MSBFIRST32(pbOtsSignature);
947 pbOtsSignature += sizeof(UINT32);
948 if (nSigType != pSigParams->lmsOtsAlgID)
949 {
950 scError = SYMCRYPT_INVALID_ARGUMENT;
951 goto cleanup;
952 }
953
954 pbRandomizer = pbOtsSignature;
955 pbOtsSignature += cbHashOutput;
956
957 SYMCRYPT_STORE_MSBFIRST32(en32LeafNumber, nLeafNumber);
958
959 LmsHashMessage(pHash, pbId, en32LeafNumber, pbRandomizer, cbHashOutput, pbMessage, cbMessage, abLmsHashedMsg, cbHashOutput);
960 nCksm = LmsOtsCalculateChecksum(abLmsHashedMsg, cbHashOutput, nWinternitzChainWidth, pSigParams->nChecksumLShiftBits);
961 SYMCRYPT_STORE_MSBFIRST16((UINT16*)&abLmsHashedMsg[cbHashOutput], (UINT16)nCksm);
962
963 SymCryptHashInit(pHash, &stateKc);
965 SymCryptHashAppend(pHash, &stateKc, en32LeafNumber, sizeof(UINT32));
967
968 SymCryptHashInit(pHash, &state);
969 for (UINT32 i = 0; i < nByteStringCount; i++)
970 {
971 BYTE a = (BYTE)SymCryptHbsGetDigit(nWinternitzChainWidth, abLmsHashedMsg, cbHashOutput + sizeof(nCksm), i);
972 PCBYTE tmp = pbOtsSignature + (i * cbHashOutput);
973
975
976 for (BYTE j = a; j < nMaxJ; j++)
977 {
979 SymCryptHashAppend(pHash, &state, en32LeafNumber, sizeof(UINT32));
980 SymCryptHashAppend(pHash, &state, en16Index, sizeof(UINT16));
981 SymCryptHashAppend(pHash, &state, &j, 1);
983 SymCryptHashResult(pHash, &state, abTmpRes, cbHashOutput);
984 tmp = abTmpRes;
985 }
986 SymCryptHashAppend(pHash, &stateKc, tmp, cbHashOutput);
987 }
988 SymCryptHashResult(pHash, &stateKc, pbOtsPubKeyCandidate, cbHashOutput);
989
990cleanup:
991 return scError;
992}
993
994static
995VOID
998 UINT32 nLeafNumber,
1001 _In_reads_bytes_(pParams->nTreeHeight * pParams->cbHashOutput) PCBYTE pbPath,
1002 _In_reads_bytes_(pParams->cbHashOutput) PCBYTE pbPubKeyCandidate,
1003 _Out_writes_bytes_(pParams->cbHashOutput) PBYTE pbRootCandidate
1004)
1005{
1006 PCSYMCRYPT_HASH pHash = pParams->pLmsHashFunction;
1007 SYMCRYPT_HASH_STATE state = { 0 };
1008 UINT32 cbHashOutput = pParams->cbHashOutput;
1009 UINT32 nIndex = 0;
1010 UINT32 nNodeNum = (1 << pParams->nTreeHeight) + nLeafNumber;
1011 PBYTE pbTemp = pbRootCandidate;
1012 BYTE en32NodeNum[sizeof(UINT32)] = { 0 };
1013
1014 SYMCRYPT_STORE_MSBFIRST32(en32NodeNum, nNodeNum);
1015 SymCryptHashInit(pHash, &state);
1017 SymCryptHashAppend(pHash, &state, en32NodeNum, sizeof(UINT32));
1019 SymCryptHashAppend(pHash, &state, pbPubKeyCandidate, cbHashOutput);
1020 SymCryptHashResult(pHash, &state, pbTemp, cbHashOutput);
1021
1022 for (nIndex = 0; nIndex < pParams->nTreeHeight; nIndex ++)
1023 {
1024 SYMCRYPT_STORE_MSBFIRST32(en32NodeNum, nNodeNum / 2);
1026 SymCryptHashAppend(pHash, &state, en32NodeNum, sizeof(UINT32));
1028 if (nNodeNum % 2)
1029 {
1030 SymCryptHashAppend(pHash, &state, pbPath + (cbHashOutput * nIndex), cbHashOutput);
1031 SymCryptHashAppend(pHash, &state, pbTemp, cbHashOutput);
1032 }
1033 else
1034 {
1035 SymCryptHashAppend(pHash, &state, pbTemp, cbHashOutput);
1036 SymCryptHashAppend(pHash, &state, pbPath + (cbHashOutput * nIndex), cbHashOutput);
1037 }
1038 SymCryptHashResult(pHash, &state, pbTemp, cbHashOutput);
1039 nNodeNum /= 2;
1040 }
1041 SYMCRYPT_ASSERT(nNodeNum <= 1);
1042
1043 memcpy(pbRootCandidate, pbTemp, cbHashOutput);
1044}
1045
1050 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
1051 SIZE_T cbMessage,
1052 UINT32 flags,
1053 _In_reads_bytes_(cbSignature) PCBYTE pbSignature,
1054 SIZE_T cbSignature)
1055{
1059
1060 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1061 UINT32 cbHashOutput = pKey->params.cbHashOutput;
1062 PCSYMCRYPT_LMS_PARAMS pLmsKeyParams = &pKey->params;
1063 PCBYTE pbLocSignature = pbSignature;
1064 BYTE abRootCandidate[SYMCRYPT_LMS_MAX_N] = { 0 };
1065 BYTE abOtsPubKeyCandidate[SYMCRYPT_LMS_MAX_N] = { 0 };
1066
1067 if (flags != 0)
1068 {
1069 scError = SYMCRYPT_INVALID_ARGUMENT;
1070 goto cleanup;
1071 }
1072
1073 if (cbSignature != SymCryptLmsSizeofSignatureFromParams(&pKey->params))
1074 {
1075 scError = SYMCRYPT_INVALID_ARGUMENT;
1076 goto cleanup;
1077 }
1078
1079 UINT32 nLeafNumber = SYMCRYPT_LOAD_MSBFIRST32(pbLocSignature);
1080 pbLocSignature += sizeof(UINT32);
1081 if (nLeafNumber >= ((UINT32)1 << pKey->params.nTreeHeight))
1082 {
1083 scError = SYMCRYPT_INVALID_ARGUMENT;
1084 goto cleanup;
1085 }
1086
1087 UINT32 nOtsSigtype = SYMCRYPT_LOAD_MSBFIRST32(pbLocSignature);
1088 pbLocSignature += sizeof(UINT32);
1089
1090 if (nOtsSigtype != pLmsKeyParams->lmsOtsAlgID)
1091 {
1092 scError = SYMCRYPT_INVALID_ARGUMENT;
1093 goto cleanup;
1094 }
1095
1096 pbLocSignature += cbHashOutput * (pKey->params.nByteStringCount + 1); // +1 is for the randomizer
1097 UINT32 nSigType = SYMCRYPT_LOAD_MSBFIRST32(pbLocSignature);
1098 pbLocSignature += sizeof(UINT32);
1099
1100 if (nSigType != pLmsKeyParams->lmsAlgID)
1101 {
1102 scError = SYMCRYPT_INVALID_ARGUMENT;
1103 goto cleanup;
1104 }
1105
1107 nLeafNumber,
1108 pbMessage,
1109 cbMessage,
1110 pbSignature + sizeof(UINT32), //the +sizeof(UINT32) is to skip the leaf number and reach the LMS-OTS signature
1112 pKey->abId,
1113 pLmsKeyParams,
1114 abOtsPubKeyCandidate);
1115 if (scError != SYMCRYPT_NO_ERROR)
1116 {
1117 goto cleanup;
1118 }
1119
1121 nLeafNumber,
1122 pLmsKeyParams,
1123 pKey->abId,
1124 pbLocSignature,
1125 abOtsPubKeyCandidate,
1126 abRootCandidate);
1127 if (!SymCryptEqual(abRootCandidate, pKey->abPublicRoot, cbHashOutput))
1128 {
1129 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1130 goto cleanup;
1131 }
1132
1133cleanup:
1134 return scError;
1135}
1136
1141 _In_reads_bytes_(cbMessage) PCBYTE pbMessage,
1142 SIZE_T cbMessage,
1143 UINT32 flags,
1144 _In_reads_bytes_(cbSignature) PCBYTE pbSignature,
1145 SIZE_T cbSignature)
1146{
1147 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1148
1152
1153 scError = SymCryptLmsVerifyInternal(
1154 pKey,
1155 pbMessage,
1156 cbMessage,
1157 flags,
1158 pbSignature,
1159 cbSignature);
1160
1161 return scError;
1162}
unsigned short UINT16
Definition: actypes.h:129
unsigned char UINT8
Definition: actypes.h:128
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
static int state
Definition: maze.c:121
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
unsigned int BOOL
Definition: ntddk_ex.h:94
const GLdouble * v
Definition: gl.h:2040
GLdouble n
Definition: glext.h:7729
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCallbackRandom(BYTE *buf, SIZE_T size)
Definition: implglue.c:56
PSYMCRYPT_LMS_KEY SYMCRYPT_CALL SymCryptLmskeyAllocate(_In_ PCSYMCRYPT_LMS_PARAMS pParams, UINT32 flags)
Definition: lms.c:543
static const SYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED LmsOtsParametersPredefined[]
Definition: lms.c:76
static VOID LmsHashMessage(_In_ PCSYMCRYPT_HASH pHash, _In_reads_bytes_(SYMCRYPT_LMS_KEY_PAIR_IDENTIFIER_SIZE) PCBYTE pbId, _In_reads_bytes_(sizeof(UINT32)) PCBYTE pbLeafNumber, _In_reads_bytes_(cbRandomizer) PCBYTE pbRandomizer, SIZE_T cbRandomizer, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, _Out_writes_bytes_(cbOut) PBYTE pbOut, SIZE_T cbOut)
Definition: lms.c:103
struct _SYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED * PSYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED
struct _SYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED SYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED
static const BYTE SYMCRYPT_LMS_D_LEAF[]
Definition: lms.c:98
struct _SYMCRYPT_LMS_PARAMETER_PREDEFINED * PSYMCRYPT_LMS_PARAMETER_PREDEFINED
static SYMCRYPT_ERROR SYMCRYPT_CALL LmsComputeOtsPubKeyCandidate(UINT32 nLeafNumber, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, _In_reads_bytes_(cbOtsSignature) PCBYTE pbOtsSignature, SIZE_T cbOtsSignature, _In_reads_bytes_(SYMCRYPT_LMS_KEY_PAIR_IDENTIFIER_SIZE) PCBYTE pbId, _In_ PCSYMCRYPT_LMS_PARAMS pSigParams, _Out_writes_bytes_(pSigParams->cbHashOutput) PBYTE pbOtsPubKeyCandidate)
Definition: lms.c:914
const SYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED * PCSYMCRYPT_LMS_OTS_PARAMETER_PREDEFINED
Definition: lms.c:74
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsSetParams(_Out_ PSYMCRYPT_LMS_PARAMS pParams, UINT32 lmsAlgID, UINT32 lmsOtsAlgID, _In_ PCSYMCRYPT_HASH pLmsHashFunction, UINT32 cbHashOutput, UINT32 nTreeHeight, UINT32 nWinternitzChainWidth)
Definition: lms.c:460
static UINT16 LmsOtsCalculateChecksum(_In_reads_bytes_(cbString) PCBYTE pbString, UINT32 cbString, UINT32 nWidth, UINT32 nLeftShift)
Definition: lms.c:170
static SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmskeyVerifyRoot(_In_ PCSYMCRYPT_LMS_KEY pKey)
Definition: lms.c:585
static VOID SYMCRYPT_CALL LmsComputeRootCandidate(UINT32 nLeafNumber, _In_ PCSYMCRYPT_LMS_PARAMS pParams, _In_reads_bytes_(SYMCRYPT_LMS_KEY_PAIR_IDENTIFIER_SIZE) PCBYTE pbId, _In_reads_bytes_(pParams->nTreeHeight *pParams->cbHashOutput) PCBYTE pbPath, _In_reads_bytes_(pParams->cbHashOutput) PCBYTE pbPubKeyCandidate, _Out_writes_bytes_(pParams->cbHashOutput) PBYTE pbRootCandidate)
Definition: lms.c:997
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsVerifyInternal(_In_ PCSYMCRYPT_LMS_KEY pKey, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, UINT32 flags, _In_reads_bytes_(cbSignature) PCBYTE pbSignature, SIZE_T cbSignature)
Definition: lms.c:1048
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmskeyGenerate(_Inout_ PSYMCRYPT_LMS_KEY pKey, UINT32 flags)
Definition: lms.c:619
SIZE_T SYMCRYPT_CALL SymCryptLmsSizeofSignatureFromParams(_In_ PCSYMCRYPT_LMS_PARAMS pParams)
Definition: lms.c:446
static const PCSYMCRYPT_HASH * LmsHashObjects[]
Definition: lms.c:12
static const BYTE SYMCRYPT_LMS_D_INTR[]
Definition: lms.c:99
static const SYMCRYPT_LMS_PARAMETER_PREDEFINED LmsParametersPredefined[]
Definition: lms.c:35
static VOID SYMCRYPT_CALL LmsOtskeySign(_In_ PSYMCRYPT_LMS_KEY pKey, UINT64 nLeafNumber, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, _In_reads_bytes_(pKey->params.cbHashOutput) PCBYTE pbRandomizer, _Out_writes_bytes_(cbSignature) PBYTE pbSignature, SIZE_T cbSignature)
Definition: lms.c:207
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmskeySetValue(_In_reads_bytes_(cbBlob) PCBYTE pbBlob, SIZE_T cbBlob, SYMCRYPT_LMSKEY_TYPE keyType, UINT32 flags, _Inout_ PSYMCRYPT_LMS_KEY pKey)
Definition: lms.c:729
VOID SYMCRYPT_CALL SymCryptLmskeyFree(_Inout_ PSYMCRYPT_LMS_KEY pKey)
Definition: lms.c:573
static const BYTE SYMCRYPT_LMS_D_MESG[]
Definition: lms.c:97
static SIZE_T SYMCRYPT_CALL LmsOtsSizeofSignatureFromParams(_In_ PCSYMCRYPT_LMS_PARAMS pParams)
Definition: lms.c:190
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsSizeofKeyBlobFromParams(_In_ PCSYMCRYPT_LMS_PARAMS pParams, SYMCRYPT_LMSKEY_TYPE keyType, _Out_ SIZE_T *pcbKey)
Definition: lms.c:516
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmskeyGetValue(_In_ PCSYMCRYPT_LMS_KEY pKey, SYMCRYPT_LMSKEY_TYPE keyType, UINT32 flags, _Out_writes_bytes_(cbBlob) PBYTE pbBlob, SIZE_T cbBlob)
Definition: lms.c:667
static const BYTE SYMCRYPT_LMS_D_PBLC[]
Definition: lms.c:96
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsSign(_Inout_ PSYMCRYPT_LMS_KEY pKey, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, UINT32 flags, _Out_writes_bytes_(cbSignature) PBYTE pbSignature, SIZE_T cbSignature)
Definition: lms.c:821
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsParamsFromAlgId(SYMCRYPT_LMS_ALGID lmsAlgID, SYMCRYPT_LMS_OTS_ALGID lmsOtsAlgID, _Out_ PSYMCRYPT_LMS_PARAMS pParams)
Definition: lms.c:365
static VOID SYMCRYPT_CALL LmsComputeNodeValue(_In_ PCSYMCRYPT_LMS_KEY pKey, UINT32 nIndex, _Out_writes_bytes_(pKey->params.cbHashOutput) PBYTE pbNodeValue, SIZE_T cbNodeValue)
Definition: lms.c:318
static VOID SYMCRYPT_CALL LmsOtskeyComputePrivate(_In_ PCSYMCRYPT_LMS_KEY pKey, _In_ UINT32 nLeafNumber, _In_ UINT32 nPIdx, _Out_writes_bytes_(pKey->params.cbHashOutput) PBYTE pbOtsPrivateKey)
Definition: lms.c:128
static VOID SYMCRYPT_CALL LmsOtskeyComputePublic(_In_ PCSYMCRYPT_LMS_KEY pKey, UINT32 nNodeIdx, _Out_writes_bytes_(pKey->params.cbHashOutput) PBYTE pbK)
Definition: lms.c:274
static VOID SYMCRYPT_CALL LmskeyWipe(_Inout_ PSYMCRYPT_LMS_KEY pKey)
Definition: lms.c:156
struct _SYMCRYPT_LMS_PARAMETER_PREDEFINED SYMCRYPT_LMS_PARAMETER_PREDEFINED
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptLmsVerify(_In_ PCSYMCRYPT_LMS_KEY pKey, _In_reads_bytes_(cbMessage) PCBYTE pbMessage, SIZE_T cbMessage, UINT32 flags, _In_reads_bytes_(cbSignature) PCBYTE pbSignature, SIZE_T cbSignature)
Definition: lms.c:1139
const SYMCRYPT_LMS_PARAMETER_PREDEFINED * PCSYMCRYPT_LMS_PARAMETER_PREDEFINED
Definition: lms.c:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BYTE * PBYTE
Definition: pedump.c:66
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
#define SYMCRYPT_IS_VALID_WINTERNITZ_WIDTH(w)
Definition: sc_lib.h:4701
VOID SYMCRYPT_CALL SymCryptHbsGetWinternitzLengths(UINT32 n, UINT32 w, _Out_ PUINT32 puLen1, _Out_ PUINT32 puLen2)
Definition: xmss.c:188
#define SYMCRYPT_LMS_PUB_KEY_SIZE(cbHashOutput)
Definition: sc_lib.h:4710
#define SYMCRYPT_LMS_KEY_PAIR_IDENTIFIER_SIZE
Definition: sc_lib.h:4702
#define SYMCRYPT_LMS_PRIV_KEY_SIZE(cbHashOutput)
Definition: sc_lib.h:4713
BYTE abPublicRoot[SYMCRYPT_LMS_MAX_N]
Definition: sc_lib.h:4732
SYMCRYPT_XMSSKEY_TYPE keyType
Definition: sc_lib.h:4525
#define SYMCRYPT_LMS_MAX_N
Definition: sc_lib.h:4703
#define SYMCRYPT_LMS_MAX_CUSTOM_TREE_HEIGHT
Definition: sc_lib.h:4706
#define SYMCRYPT_RUN_SELFTEST_ONCE(AlgorithmSelftestFunction, AlgorithmSelftestFlag)
Definition: sc_lib.h:3686
UINT32 SYMCRYPT_CALL SymCryptHbsGetDigit(UINT32 width, _In_ PCBYTE pbBuffer, SIZE_T cbBuffer, UINT32 index)
Definition: xmss.c:1429
#define SYMCRYPT_ARRAY_SIZE(_x)
Definition: sc_lib.h:342
#define SYMCRYPT_LMS_CHECKSUM_SIZE
Definition: sc_lib.h:4707
SYMCRYPT_LMS_OTS_ALGID lmsOtsAlgId
Definition: lms.c:62
SYMCRYPT_LMS_ALGID lmsAlgId
Definition: lms.c:19
#define max(a, b)
Definition: svc.c:63
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
enum _SYMCRYPT_LMSKEY_TYPE SYMCRYPT_LMSKEY_TYPE
const PCSYMCRYPT_HASH SymCryptShake256HashAlgorithm
Definition: shake.c:93
VOID SYMCRYPT_CALL SymCryptLmsSelftest(void)
VOID SYMCRYPT_CALL SymCryptHashAppend(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:182
#define SYMCRYPT_LOAD_MSBFIRST32(p)
Definition: symcrypt.h:303
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
const PCSYMCRYPT_HASH SymCryptSha256Algorithm
Definition: sha256.c:46
VOID SYMCRYPT_CALL SymCryptHashInit(_In_ PCSYMCRYPT_HASH pHash, _Out_writes_bytes_(pHash->stateSize) PVOID pState)
Definition: hash.c:173
@ SYMCRYPT_LMS_OTS_SHA256_N24_W4
Definition: symcrypt.h:9605
@ SYMCRYPT_LMS_OTS_SHAKE_N32_W1
Definition: symcrypt.h:9607
@ SYMCRYPT_LMS_OTS_SHAKE_N32_W8
Definition: symcrypt.h:9610
@ SYMCRYPT_LMS_OTS_SHAKE_N24_W4
Definition: symcrypt.h:9613
@ SYMCRYPT_LMS_OTS_SHA256_N32_W8
Definition: symcrypt.h:9602
@ SYMCRYPT_LMS_OTS_SHA256_N32_W1
Definition: symcrypt.h:9599
@ SYMCRYPT_LMS_OTS_SHA256_N24_W2
Definition: symcrypt.h:9604
@ SYMCRYPT_LMS_OTS_SHAKE_N32_W2
Definition: symcrypt.h:9608
@ SYMCRYPT_LMS_OTS_SHA256_N32_W4
Definition: symcrypt.h:9601
@ SYMCRYPT_LMS_OTS_SHAKE_N24_W2
Definition: symcrypt.h:9612
@ SYMCRYPT_LMS_OTS_SHAKE_N32_W4
Definition: symcrypt.h:9609
@ SYMCRYPT_LMS_OTS_SHA256_N24_W8
Definition: symcrypt.h:9606
@ SYMCRYPT_LMS_OTS_SHA256_N32_W2
Definition: symcrypt.h:9600
@ SYMCRYPT_LMS_OTS_SHAKE_N24_W1
Definition: symcrypt.h:9611
@ SYMCRYPT_LMS_OTS_SHAKE_N24_W8
Definition: symcrypt.h:9614
@ SYMCRYPT_LMS_OTS_SHA256_N24_W1
Definition: symcrypt.h:9603
@ SYMCRYPT_LMSKEY_TYPE_PRIVATE
Definition: symcrypt.h:9624
@ SYMCRYPT_LMSKEY_TYPE_PUBLIC
Definition: symcrypt.h:9623
@ SYMCRYPT_LMSKEY_TYPE_NONE
Definition: symcrypt.h:9622
#define SYMCRYPT_STORE_MSBFIRST16(p, v)
Definition: symcrypt.h:310
enum _SYMCRYPT_LMS_OTS_ALGID SYMCRYPT_LMS_OTS_ALGID
enum _SYMCRYPT_LMS_ALGID SYMCRYPT_LMS_ALGID
#define SYMCRYPT_FLAG_LMSKEY_VERIFY_ROOT
Definition: symcrypt.h:9618
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
BOOLEAN SYMCRYPT_CALL SymCryptEqual(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, SIZE_T cbBytes)
Definition: equal.c:11
@ SYMCRYPT_LMS_SHA256_M24_H20
Definition: symcrypt.h:9577
@ SYMCRYPT_LMS_SHAKE_M32_H25
Definition: symcrypt.h:9583
@ SYMCRYPT_LMS_SHAKE_M24_H5
Definition: symcrypt.h:9584
@ SYMCRYPT_LMS_SHAKE_M32_H10
Definition: symcrypt.h:9580
@ SYMCRYPT_LMS_SHA256_M24_H15
Definition: symcrypt.h:9576
@ SYMCRYPT_LMS_SHA256_M24_H25
Definition: symcrypt.h:9578
@ SYMCRYPT_LMS_SHA256_M32_H25
Definition: symcrypt.h:9573
@ SYMCRYPT_LMS_SHAKE_M24_H20
Definition: symcrypt.h:9587
@ SYMCRYPT_LMS_SHA256_M32_H5
Definition: symcrypt.h:9569
@ SYMCRYPT_LMS_SHA256_M32_H20
Definition: symcrypt.h:9572
@ SYMCRYPT_LMS_SHA256_M32_H10
Definition: symcrypt.h:9570
@ SYMCRYPT_LMS_SHAKE_M24_H25
Definition: symcrypt.h:9588
@ SYMCRYPT_LMS_SHA256_M32_H15
Definition: symcrypt.h:9571
@ SYMCRYPT_LMS_SHA256_M24_H10
Definition: symcrypt.h:9575
@ SYMCRYPT_LMS_SHAKE_M24_H15
Definition: symcrypt.h:9586
@ SYMCRYPT_LMS_SHAKE_M24_H10
Definition: symcrypt.h:9585
@ SYMCRYPT_LMS_SHA256_M24_H5
Definition: symcrypt.h:9574
@ SYMCRYPT_LMS_SHAKE_M32_H5
Definition: symcrypt.h:9579
@ SYMCRYPT_LMS_SHAKE_M32_H15
Definition: symcrypt.h:9581
@ SYMCRYPT_LMS_SHAKE_M32_H20
Definition: symcrypt.h:9582
VOID SYMCRYPT_CALL SymCryptHashResult(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:193
SYMCRYPT_ERROR
Definition: symcrypt.h:227
@ SYMCRYPT_SELFTEST_ALGORITHM_LMS
#define SYMCRYPT_CALL
const SYMCRYPT_LMS_PARAMS * PCSYMCRYPT_LMS_PARAMS
UINT32 cbHashOutput
UINT32 nByteStringCount
PCBYTE SIZE_T cbKey
SYMCRYPT_LMS_PARAMS * PSYMCRYPT_LMS_PARAMS
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
PCSYMCRYPT_HASH pLmsHashFunction
#define SYMCRYPT_SET_MAGIC(p)
const SYMCRYPT_LMS_KEY * PCSYMCRYPT_LMS_KEY
SYMCRYPT_LMS_KEY * PSYMCRYPT_LMS_KEY
PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey
UINT32 cbSize
UINT32 nWinternitzChainWidth
UINT32 nTreeHeight
const BYTE * PCBYTE
struct _SYMCRYPT_LMS_KEY SYMCRYPT_LMS_KEY
UINT32 lmsOtsAlgID
#define SYMCRYPT_CHECK_MAGIC(p)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193