@@ -166,20 +166,6 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
166166 CK_RV rv ;
167167 CK_SESSION_HANDLE session ;
168168 CK_OBJECT_HANDLE key ;
169-
170- printf ("=== NSS PKCS#12 PBE SHA-256 HMAC Key Generation Example ===\n\n" );
171-
172- /* Initialize PKCS#11 and open session */
173- rv = pkcs11_init (library , & session );
174- if (rv != CKR_OK ) {
175- printf ("ERROR: PKCS#11 initialization failed: 0x%08lX\n" , rv );
176- return -1 ;
177- }
178-
179- /* Example 1: Basic key generation */
180- printf ("1. Basic Key Generation\n" );
181- printf (" Purpose: Generate a 256-bit encryption key from password\n\n" );
182-
183169 /* Example password and salt (in real use, these should be secure) */
184170 CK_BYTE password [] = "MySecurePassword2024" ;
185171 CK_BYTE salt [] = {
@@ -188,35 +174,13 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
188174 };
189175 CK_ULONG iterationCount = 100000 ; /* Modern recommended minimum */
190176 CK_ULONG keyLength = 32 ; /* 256-bit AES key */
191-
192- printf (" Password: %s\n" , (char * )password );
193- print_hex (" Salt" , salt , sizeof (salt ));
194- printf (" Iterations: %lu\n" , iterationCount );
195- printf (" Key Length: %lu bytes (%lu bits)\n\n" , keyLength , keyLength * 8 );
196-
197- /* Set up PBE parameters */
198- CK_PBE_PARAMS pbeParams = {
199- NULL ,
200- password ,
201- strlen ((char * )password ),
202- salt ,
203- sizeof (salt ),
204- iterationCount
205- };
206-
207- CK_MECHANISM mechanism = {
208- CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN ,
209- & pbeParams ,
210- sizeof (pbeParams )
211- };
212-
213- /* Define key attributes */
177+ CK_PBE_PARAMS pbeParams ;
178+ CK_MECHANISM mechanism ;
214179 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY ;
215180 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET ;
216181 CK_BBOOL ckTrue = CK_TRUE ;
217182 CK_BBOOL ckFalse = CK_FALSE ;
218183 CK_BYTE keyLabel [] = "PKCS12-PBE-Generated-Key" ;
219-
220184 CK_ATTRIBUTE keyTemplate [] = {
221185 {CKA_CLASS , & keyClass , sizeof (keyClass )},
222186 {CKA_KEY_TYPE , & keyType , sizeof (keyType )},
@@ -228,6 +192,108 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
228192 {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
229193 };
230194 CK_ULONG keyTemplateCount = sizeof (keyTemplate ) / sizeof (keyTemplate [0 ]);
195+ CK_BYTE keyValue [64 ];
196+ CK_ULONG keyValueLen = sizeof (keyValue );
197+ CK_ATTRIBUTE getTemplate [] = {
198+ {CKA_VALUE , keyValue , keyValueLen }
199+ };
200+ struct {
201+ CK_ULONG length ;
202+ const char * purpose ;
203+ } keyLengths [] = {
204+ {16 , "AES-128 encryption" },
205+ {24 , "AES-192 encryption" },
206+ {32 , "AES-256 encryption" },
207+ {64 , "HMAC-SHA512 authentication" }
208+ };
209+ int i ;
210+ CK_OBJECT_HANDLE testKey ;
211+ CK_ULONG testLen ;
212+ CK_OBJECT_HANDLE prodKey ;
213+ CK_BBOOL sensitive = CK_TRUE ;
214+ CK_BBOOL nonExtractable = CK_FALSE ; /* Set to CK_TRUE for production */
215+ CK_BYTE prodLabel [] = "Production-PKCS12-Key" ;
216+ CK_ATTRIBUTE prodTemplate [] = {
217+ {CKA_CLASS , & keyClass , sizeof (keyClass )},
218+ {CKA_KEY_TYPE , & keyType , sizeof (keyType )},
219+ {CKA_VALUE_LEN , & keyLength , sizeof (keyLength )},
220+ {CKA_LABEL , prodLabel , sizeof (prodLabel ) - 1 },
221+ {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
222+ {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
223+ {CKA_SENSITIVE , & sensitive , sizeof (sensitive )},
224+ {CKA_EXTRACTABLE , & nonExtractable , sizeof (nonExtractable )},
225+ {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
226+ };
227+ CK_ULONG prodTemplateCount = sizeof (prodTemplate ) / sizeof (prodTemplate [0 ]);
228+ CK_OBJECT_HANDLE aesKey ;
229+ CK_OBJECT_CLASS aesKeyClass = CKO_SECRET_KEY ;
230+ CK_KEY_TYPE aesKeyType = CKK_AES ;
231+ CK_ULONG aesKeyLength = 32 ; /* 256-bit AES key */
232+ CK_BYTE aesKeyLabel [] = "PKCS12-PBE-AES-Key" ;
233+ CK_ATTRIBUTE aesKeyTemplate [] = {
234+ {CKA_CLASS , & aesKeyClass , sizeof (aesKeyClass )},
235+ {CKA_KEY_TYPE , & aesKeyType , sizeof (aesKeyType )},
236+ {CKA_VALUE_LEN , & aesKeyLength , sizeof (aesKeyLength )},
237+ {CKA_LABEL , aesKeyLabel , sizeof (aesKeyLabel ) - 1 },
238+ {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
239+ {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
240+ {CKA_EXTRACTABLE , & ckTrue , sizeof (ckTrue )},
241+ {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
242+ };
243+ CK_ULONG aesKeyTemplateCount = sizeof (aesKeyTemplate ) / sizeof (aesKeyTemplate [0 ]);
244+ CK_BYTE plaintext [] = "Hello, PKCS#12 PBE!" ;
245+ CK_BYTE ciphertext [256 ];
246+ CK_ULONG ciphertextLen = sizeof (ciphertext );
247+ CK_BYTE decrypted [256 ];
248+ CK_ULONG decryptedLen = sizeof (decrypted );
249+ CK_BYTE iv [16 ] = {0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
250+ 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F };
251+ CK_MECHANISM encMech = { CKM_AES_CBC_PAD , iv , sizeof (iv ) };
252+ CK_ULONG plaintextLen ;
253+ CK_BYTE extractedKeyValue [32 ];
254+ CK_ULONG extractedKeyValueLen = sizeof (extractedKeyValue );
255+ CK_ATTRIBUTE extractTemplate [] = {
256+ {CKA_VALUE , extractedKeyValue , extractedKeyValueLen }
257+ };
258+ CK_OBJECT_HANDLE newAesKey ;
259+ CK_ATTRIBUTE newKeyTemplate [] = {
260+ {CKA_CLASS , & aesKeyClass , sizeof (aesKeyClass )},
261+ {CKA_KEY_TYPE , & aesKeyType , sizeof (aesKeyType )},
262+ {CKA_VALUE , extractedKeyValue , 0 }, /* Will be set later */
263+ {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
264+ {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
265+ {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
266+ };
267+
268+ printf ("=== NSS PKCS#12 PBE SHA-256 HMAC Key Generation Example ===\n\n" );
269+
270+ /* Initialize PKCS#11 and open session */
271+ rv = pkcs11_init (library , & session );
272+ if (rv != CKR_OK ) {
273+ printf ("ERROR: PKCS#11 initialization failed: 0x%08lX\n" , rv );
274+ return -1 ;
275+ }
276+
277+ /* Example 1: Basic key generation */
278+ printf ("1. Basic Key Generation\n" );
279+ printf (" Purpose: Generate a 256-bit encryption key from password\n\n" );
280+
281+ printf (" Password: %s\n" , (char * )password );
282+ print_hex (" Salt" , salt , sizeof (salt ));
283+ printf (" Iterations: %lu\n" , iterationCount );
284+ printf (" Key Length: %lu bytes (%lu bits)\n\n" , keyLength , keyLength * 8 );
285+
286+ /* Set up PBE parameters */
287+ pbeParams .pInitVector = NULL ;
288+ pbeParams .pPassword = password ;
289+ pbeParams .ulPasswordLen = strlen ((char * )password );
290+ pbeParams .pSalt = salt ;
291+ pbeParams .ulSaltLen = sizeof (salt );
292+ pbeParams .ulIteration = iterationCount ;
293+
294+ mechanism .mechanism = CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN ;
295+ mechanism .pParameter = & pbeParams ;
296+ mechanism .ulParameterLen = sizeof (pbeParams );
231297
232298 /* Generate the key */
233299 printf (" Generating key...\n" );
@@ -250,11 +316,6 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
250316 printf (" ✓ Key generated successfully (handle: %lu)\n\n" , key );
251317
252318 /* Retrieve and display key information */
253- CK_BYTE keyValue [64 ];
254- CK_ULONG keyValueLen = sizeof (keyValue );
255- CK_ATTRIBUTE getTemplate [] = {
256- {CKA_VALUE , keyValue , keyValueLen }
257- };
258319
259320 rv = funcList -> C_GetAttributeValue (session , key , getTemplate , 1 );
260321 if (rv == CKR_OK ) {
@@ -271,19 +332,8 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
271332 printf ("2. Multiple Key Lengths Example\n" );
272333 printf (" Purpose: Generate keys for different cryptographic needs\n\n" );
273334
274- struct {
275- CK_ULONG length ;
276- const char * purpose ;
277- } keyLengths [] = {
278- {16 , "AES-128 encryption" },
279- {24 , "AES-192 encryption" },
280- {32 , "AES-256 encryption" },
281- {64 , "HMAC-SHA512 authentication" }
282- };
283-
284- for (int i = 0 ; i < 4 ; i ++ ) {
285- CK_OBJECT_HANDLE testKey ;
286- CK_ULONG testLen = keyLengths [i ].length ;
335+ for (i = 0 ; i < 4 ; i ++ ) {
336+ testLen = keyLengths [i ].length ;
287337
288338 keyTemplate [2 ].pValue = & testLen ; /* Update CKA_VALUE_LEN */
289339
@@ -312,24 +362,6 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
312362 printf ("4. Production Key Generation\n" );
313363 printf (" Purpose: Generate a non-extractable key for production use\n\n" );
314364
315- CK_OBJECT_HANDLE prodKey ;
316- CK_BBOOL sensitive = CK_TRUE ;
317- CK_BBOOL nonExtractable = CK_FALSE ; /* Set to CK_TRUE for production */
318- CK_BYTE prodLabel [] = "Production-PKCS12-Key" ;
319-
320- CK_ATTRIBUTE prodTemplate [] = {
321- {CKA_CLASS , & keyClass , sizeof (keyClass )},
322- {CKA_KEY_TYPE , & keyType , sizeof (keyType )},
323- {CKA_VALUE_LEN , & keyLength , sizeof (keyLength )},
324- {CKA_LABEL , prodLabel , sizeof (prodLabel ) - 1 },
325- {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
326- {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
327- {CKA_SENSITIVE , & sensitive , sizeof (sensitive )},
328- {CKA_EXTRACTABLE , & nonExtractable , sizeof (nonExtractable )},
329- {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
330- };
331- CK_ULONG prodTemplateCount = sizeof (prodTemplate ) / sizeof (prodTemplate [0 ]);
332-
333365 rv = funcList -> C_GenerateKey (session , & mechanism , prodTemplate ,
334366 prodTemplateCount , & prodKey );
335367 if (rv == CKR_OK ) {
@@ -343,25 +375,6 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
343375 printf ("5. AES Key Generation and Usage Test\n" );
344376 printf (" Purpose: Generate an AES key using PBE and test encryption\n\n" );
345377
346- /* Generate an AES key specifically for encryption testing */
347- CK_OBJECT_HANDLE aesKey ;
348- CK_OBJECT_CLASS aesKeyClass = CKO_SECRET_KEY ;
349- CK_KEY_TYPE aesKeyType = CKK_AES ;
350- CK_ULONG aesKeyLength = 32 ; /* 256-bit AES key */
351- CK_BYTE aesKeyLabel [] = "PKCS12-PBE-AES-Key" ;
352-
353- CK_ATTRIBUTE aesKeyTemplate [] = {
354- {CKA_CLASS , & aesKeyClass , sizeof (aesKeyClass )},
355- {CKA_KEY_TYPE , & aesKeyType , sizeof (aesKeyType )},
356- {CKA_VALUE_LEN , & aesKeyLength , sizeof (aesKeyLength )},
357- {CKA_LABEL , aesKeyLabel , sizeof (aesKeyLabel ) - 1 },
358- {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
359- {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
360- {CKA_EXTRACTABLE , & ckTrue , sizeof (ckTrue )},
361- {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
362- };
363- CK_ULONG aesKeyTemplateCount = sizeof (aesKeyTemplate ) / sizeof (aesKeyTemplate [0 ]);
364-
365378 printf (" Generating AES-256 key using PBE...\n" );
366379 rv = funcList -> C_GenerateKey (session , & mechanism , aesKeyTemplate ,
367380 aesKeyTemplateCount , & aesKey );
@@ -372,23 +385,12 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
372385 printf (" ✓ AES key generated successfully (handle: %lu)\n" , aesKey );
373386
374387 /* Test encryption/decryption with the AES key */
375- CK_BYTE plaintext [] = "Hello, PKCS#12 PBE!" ;
376- CK_BYTE ciphertext [256 ];
377- CK_ULONG ciphertextLen = sizeof (ciphertext );
378- CK_BYTE decrypted [256 ];
379- CK_ULONG decryptedLen = sizeof (decrypted );
380-
381- /* Use AES-CBC-PAD mode which handles padding automatically */
382- CK_BYTE iv [16 ] = {0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
383- 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F };
384- CK_MECHANISM encMech = { CKM_AES_CBC_PAD , iv , sizeof (iv ) };
385-
386388 printf (" Plaintext: %s\n" , plaintext );
387389 print_hex (" IV" , iv , sizeof (iv ));
388390 printf (" Testing AES-CBC-PAD encryption...\n" );
389391
390392 /* Use original plaintext without manual padding since CBC_PAD handles it */
391- CK_ULONG plaintextLen = strlen ((char * )plaintext );
393+ plaintextLen = strlen ((char * )plaintext );
392394
393395 rv = funcList -> C_EncryptInit (session , & encMech , aesKey );
394396 if (rv == CKR_OK ) {
@@ -435,26 +437,13 @@ static int demonstrate_pkcs12_pbe_key_generation(const char* library)
435437 printf (" Trying to extract and re-import key...\n" );
436438
437439 /* Try to extract the PBE-generated key value and create a new AES key */
438- CK_BYTE extractedKeyValue [32 ];
439- CK_ULONG extractedKeyValueLen = sizeof (extractedKeyValue );
440- CK_ATTRIBUTE extractTemplate [] = {
441- {CKA_VALUE , extractedKeyValue , extractedKeyValueLen }
442- };
443440
444441 rv = funcList -> C_GetAttributeValue (session , aesKey , extractTemplate , 1 );
445442 if (rv == CKR_OK ) {
446443 printf (" Extracted key value, creating new AES key object...\n" );
447444
448445 /* Create a new AES key from the extracted value */
449- CK_OBJECT_HANDLE newAesKey ;
450- CK_ATTRIBUTE newKeyTemplate [] = {
451- {CKA_CLASS , & aesKeyClass , sizeof (aesKeyClass )},
452- {CKA_KEY_TYPE , & aesKeyType , sizeof (aesKeyType )},
453- {CKA_VALUE , extractedKeyValue , extractTemplate [0 ].ulValueLen },
454- {CKA_ENCRYPT , & ckTrue , sizeof (ckTrue )},
455- {CKA_DECRYPT , & ckTrue , sizeof (ckTrue )},
456- {CKA_TOKEN , & ckFalse , sizeof (ckFalse )}
457- };
446+ newKeyTemplate [2 ].ulValueLen = extractTemplate [0 ].ulValueLen ;
458447
459448 rv = funcList -> C_CreateObject (session , newKeyTemplate ,
460449 sizeof (newKeyTemplate )/sizeof (newKeyTemplate [0 ]),
0 commit comments