pkcs5_decrypt.c
Go to the documentation of this file.
1 /**
2  * @file pkcs5_decrypt.c
3  * @brief PKCS #5 decryption routines
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/pkcs5_common.h"
37 #include "pkix/pkcs5_decrypt.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
41 #include "cipher_modes/cbc.h"
42 #include "mac/hmac.h"
43 #include "kdf/pbkdf.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (PKCS5_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief PKCS #5 decryption operation
52  * @param[in] encryptionAlgoId Encryption algorithm identifier
53  * @param[in] password NULL-terminated string containing the password
54  * @param[in] ciphertext Pointer to the ciphertext data
55  * @param[in] ciphertextLen Length of the ciphertext data, in bytes
56  * @param[out] plaintext Pointer to the plaintext data
57  * @param[out] plaintextLen Length of the plaintext data, in bytes
58  * @return Error code
59  **/
60 
61 error_t pkcs5Decrypt(const X509AlgoId *encryptionAlgoId,
62  const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen,
63  uint8_t *plaintext, size_t *plaintextLen)
64 {
65  error_t error;
66 
67  //Check parameters
68  if(encryptionAlgoId != NULL && password != NULL && ciphertext != NULL &&
69  plaintext != NULL && plaintextLen != NULL)
70  {
71  //Check encryption algorithm identifier
72  if(!oidComp(encryptionAlgoId->oid.value, encryptionAlgoId->oid.length,
73  PBES2_OID, sizeof(PBES2_OID)))
74  {
75  //Perform PBES2 decryption operation
76  error = pkcs5DecryptPbes2(encryptionAlgoId, password, ciphertext,
77  ciphertextLen, plaintext, plaintextLen);
78  }
79  else
80  {
81  //Perform PBES1 decryption operation
82  error = pkcs5DecryptPbes1(encryptionAlgoId, password, ciphertext,
83  ciphertextLen, plaintext, plaintextLen);
84  }
85  }
86  else
87  {
88  //Report an error
90  }
91 
92  //Return status code
93  return error;
94 }
95 
96 
97 /**
98  * @brief PBES1 decryption operation
99  * @param[in] encryptionAlgoId Encryption algorithm identifier
100  * @param[in] password NULL-terminated string containing the password
101  * @param[in] ciphertext Pointer to the ciphertext data
102  * @param[in] ciphertextLen Length of the ciphertext data, in bytes
103  * @param[out] plaintext Pointer to the plaintext data
104  * @param[out] plaintextLen Length of the plaintext data, in bytes
105  * @return Error code
106  **/
107 
108 error_t pkcs5DecryptPbes1(const X509AlgoId *encryptionAlgoId,
109  const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen,
110  uint8_t *plaintext, size_t *plaintextLen)
111 {
112  error_t error;
113  size_t i;
114  size_t psLen;
115  size_t passwordLen;
116  uint8_t *k;
117  uint8_t *iv;
118  uint8_t dk[16];
119  Pkcs5Pbes1Params pbes1Params;
120  const HashAlgo *hashAlgo;
121  const CipherAlgo *cipherAlgo;
122 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
123  CipherContext *cipherContext;
124 #else
125  CipherContext cipherContext[1];
126 #endif
127 
128  //Check the length of the encrypted data
129  if(ciphertextLen == 0)
131 
132  //Obtain the eight-octet salt S and the iteration count c
133  error = pkcs5ParsePbes1Params(encryptionAlgoId->params.value,
134  encryptionAlgoId->params.length, &pbes1Params);
135  //Any error to report?
136  if(error)
137  return error;
138 
139  //Retrieve hash algorithm
140  hashAlgo = pkcs5GetPbes1HashAlgo(encryptionAlgoId->oid.value,
141  encryptionAlgoId->oid.length);
142  //Invalid hash algorithm?
143  if(hashAlgo == NULL)
145 
146  //Retrieve cipher algorithm
147  cipherAlgo = pkcs5GetPbes1CipherAlgo(encryptionAlgoId->oid.value,
148  encryptionAlgoId->oid.length);
149  //Invalid cipher algorithm?
150  if(cipherAlgo == NULL)
152 
153  //If the length in octets of the ciphertext C is not a multiple of eight,
154  //output a decryption error and stop
155  if((ciphertextLen % cipherAlgo->blockSize) != 0)
157 
158  //Retrieve the length of the password
159  passwordLen = osStrlen(password);
160 
161  //Apply the PBKDF1 key derivation function to the password P, the salt S,
162  //and the iteration count c to produce a derived key DK of length 16 octets
163  error = pbkdf1(hashAlgo, (uint8_t *) password, passwordLen,
164  pbes1Params.salt.value, pbes1Params.salt.length,
165  pbes1Params.iterationCount, dk, 16);
166  //Any error to report?
167  if(error)
168  return error;
169 
170  //Separate the derived key DK into an encryption key K consisting of the
171  //first eight octets of DK and an initialization vector IV consisting of
172  //the next eight octets
173  k = dk;
174  iv = dk + 8;
175 
176 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
177  //Allocate a memory buffer to hold the cipher context
178  cipherContext = cryptoAllocMem(cipherAlgo->contextSize);
179  //Failed to allocate memory?
180  if(cipherContext == NULL)
181  return ERROR_OUT_OF_MEMORY;
182 #endif
183 
184  //Load encryption key K
185  error = cipherAlgo->init(cipherContext, k, 8);
186 
187  //Check status code
188  if(!error)
189  {
190  //Decrypt the ciphertext C with the underlying block cipher (DES or
191  //RC2) in CBC mode under the encryption key K with initialization
192  //vector IV to recover an encoded message EM
193  error = cbcDecrypt(cipherAlgo, cipherContext, iv, ciphertext,
194  plaintext, ciphertextLen);
195  }
196 
197  //Erase cipher context
198  cipherAlgo->deinit(cipherContext);
199 
200 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
201  //Release previously allocated memory
202  cryptoFreeMem(cipherContext);
203 #endif
204 
205  //Any error to report?
206  if(error)
207  return error;
208 
209  //Retrieve the length of the padding string PS
210  psLen = plaintext[ciphertextLen - 1];
211 
212  //Ensure that psLen is between 1 and 8
213  if(psLen < 1 || psLen > 8)
215 
216  //Malformed padding?
217  if(psLen > ciphertextLen)
219 
220  //Verify padding string
221  for(i = 0; i < psLen; i++)
222  {
223  //The padding string PS consists of psLen octets each with value psLen
224  if(plaintext[ciphertextLen - i - 1] != psLen)
226  }
227 
228  //Strip padding bytes from the encoded message EM
229  *plaintextLen = ciphertextLen - psLen;
230 
231  //Successful processing
232  return NO_ERROR;
233 }
234 
235 
236 /**
237  * @brief PBES2 decryption operation
238  * @param[in] encryptionAlgoId Encryption algorithm identifier
239  * @param[in] password NULL-terminated string containing the password
240  * @param[in] ciphertext Pointer to the ciphertext data
241  * @param[in] ciphertextLen Length of the ciphertext data, in bytes
242  * @param[out] plaintext Pointer to the plaintext data
243  * @param[out] plaintextLen Length of the plaintext data, in bytes
244  * @return Error code
245  **/
246 
247 error_t pkcs5DecryptPbes2(const X509AlgoId *encryptionAlgoId,
248  const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen,
249  uint8_t *plaintext, size_t *plaintextLen)
250 {
251  error_t error;
252  size_t i;
253  size_t dkLen;
254  size_t psLen;
255  size_t passwordLen;
256  uint8_t dk[32];
257  uint8_t iv[16];
258  Pkcs5Pbes2Params pbes2Params;
259  const HashAlgo *hashAlgo;
260  const CipherAlgo *cipherAlgo;
261 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
262  CipherContext *cipherContext;
263 #else
264  CipherContext cipherContext[1];
265 #endif
266 
267  //Check the length of the encrypted data
268  if(ciphertextLen == 0)
270 
271  //Obtain the salt S for the operation and the iteration count c for the
272  //key derivation function
273  error = pkcs5ParsePbes2Params(encryptionAlgoId->params.value,
274  encryptionAlgoId->params.length, &pbes2Params);
275  //Any error to report?
276  if(error)
277  return error;
278 
279  //Retrieve PRF hash algorithm
281  pbes2Params.keyDerivationFunc.prfAlgoId.length);
282  //Invalid hash algorithm?
283  if(hashAlgo == NULL)
285 
286  //Retrieve cipher algorithm
287  cipherAlgo = pkcs5GetPbes2CipherAlgo(pbes2Params.encryptionScheme.oid.value,
288  pbes2Params.encryptionScheme.oid.length);
289  //Invalid cipher algorithm?
290  if(cipherAlgo == NULL)
292 
293  //Obtain the key length in octets, dkLen, for the derived key for the
294  //underlying encryption scheme
295  dkLen = pkcs5GetPbes2KeyLength(pbes2Params.encryptionScheme.oid.value,
296  pbes2Params.encryptionScheme.oid.length);
297  //Invalid key length?
298  if(dkLen == 0)
300 
301  //If the length in octets of the ciphertext C is not a multiple of the block
302  //size, output a decryption error and stop
303  if((ciphertextLen % cipherAlgo->blockSize) != 0)
305 
306  //Check the length of the IV
307  if(pbes2Params.encryptionScheme.iv.length != cipherAlgo->blockSize)
309 
310  //Copy initialization vector
311  osMemcpy(iv, pbes2Params.encryptionScheme.iv.value, cipherAlgo->blockSize);
312 
313  //Retrieve the length of the password
314  passwordLen = osStrlen(password);
315 
316  //Apply the selected KDF function to the password P, the salt S, and the
317  //iteration count c to produce a derived key DK of length dkLen octets
318  error = pbkdf2(hashAlgo, (uint8_t *) password, passwordLen,
319  pbes2Params.keyDerivationFunc.salt.value,
320  pbes2Params.keyDerivationFunc.salt.length,
321  pbes2Params.keyDerivationFunc.iterationCount, dk, dkLen);
322  //Any error to report?
323  if(error)
324  return error;
325 
326 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
327  //Allocate a memory buffer to hold the cipher context
328  cipherContext = cryptoAllocMem(cipherAlgo->contextSize);
329  //Failed to allocate memory?
330  if(cipherContext == NULL)
331  return ERROR_OUT_OF_MEMORY;
332 #endif
333 
334  //Load encryption key DK
335  error = cipherAlgo->init(cipherContext, dk, dkLen);
336 
337  //Check status code
338  if(!error)
339  {
340  //Decrypt the ciphertext C with the underlying encryption scheme
341  //under the derived key DK to recover a message M
342  error = cbcDecrypt(cipherAlgo, cipherContext, iv, ciphertext,
343  plaintext, ciphertextLen);
344  }
345 
346  //Erase cipher context
347  cipherAlgo->deinit(cipherContext);
348 
349 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
350  //Release previously allocated memory
351  cryptoFreeMem(cipherContext);
352 #endif
353 
354  //Any error to report?
355  if(error)
356  return error;
357 
358  //Retrieve the length of the padding string PS
359  psLen = plaintext[ciphertextLen - 1];
360 
361  //Ensure that psLen is valid
362  if(psLen < 1 || psLen > cipherAlgo->blockSize)
364 
365  //Malformed padding?
366  if(psLen > ciphertextLen)
368 
369  //Verify padding string
370  for(i = 0; i < psLen; i++)
371  {
372  //The padding string PS consists of psLen octets each with value psLen
373  if(plaintext[ciphertextLen - i - 1] != psLen)
375  }
376 
377  //Strip padding bytes from the encoded message EM
378  *plaintextLen = ciphertextLen - psLen;
379 
380  //Successful processing
381  return NO_ERROR;
382 }
383 
384 
385 /**
386  * @brief Parse PBES1 parameters
387  * @param[in] data Pointer to the ASN.1 structure to parse
388  * @param[in] length Length of the ASN.1 structure
389  * @param[out] pbes1Params Information resulting from the parsing process
390  * @return Error code
391  **/
392 
393 error_t pkcs5ParsePbes1Params(const uint8_t *data, size_t length,
394  Pkcs5Pbes1Params *pbes1Params)
395 {
396  error_t error;
397  int32_t value;
398  Asn1Tag tag;
399 
400  //The PBES1 parameters are encapsulated within a sequence
401  error = asn1ReadSequence(data, length, &tag);
402  //Failed to decode ASN.1 tag?
403  if(error)
404  return error;
405 
406  //Point to the first field of the sequence
407  data = tag.value;
408  length = tag.length;
409 
410  //Read salt
411  error = asn1ReadOctetString(data, length, &tag);
412  //Failed to decode ASN.1 tag?
413  if(error)
414  return error;
415 
416  //The salt must be an eight-octet string
417  if(tag.length != 8)
418  return ERROR_INVALID_SYNTAX;
419 
420  //Save salt value
421  pbes1Params->salt.value = tag.value;
422  pbes1Params->salt.length = tag.length;
423 
424  //Point to the next field
425  data += tag.totalLength;
426  length -= tag.totalLength;
427 
428  //Read iteration count
429  error = asn1ReadInt32(data, length, &tag, &value);
430  //Failed to decode ASN.1 tag?
431  if(error)
432  return error;
433 
434  //The iteration count must be a positive integer
435  if(value < 0)
436  return ERROR_INVALID_SYNTAX;
437 
438  //Save iteration count
439  pbes1Params->iterationCount = value;
440 
441  //Successful processing
442  return NO_ERROR;
443 }
444 
445 
446 /**
447  * @brief Parse PBES2 parameters
448  * @param[in] data Pointer to the ASN.1 structure to parse
449  * @param[in] length Length of the ASN.1 structure
450  * @param[out] pbes2Params Information resulting from the parsing process
451  * @return Error code
452  **/
453 
454 error_t pkcs5ParsePbes2Params(const uint8_t *data, size_t length,
455  Pkcs5Pbes2Params *pbes2Params)
456 {
457  error_t error;
458  size_t n;
459  Asn1Tag tag;
460 
461  //The PBES2 parameters are encapsulated within a sequence
462  error = asn1ReadSequence(data, length, &tag);
463  //Failed to decode ASN.1 tag?
464  if(error)
465  return error;
466 
467  //Point to the first field of the sequence
468  data = tag.value;
469  length = tag.length;
470 
471  //KeyDerivationFunc identifies the underlying key derivation function. It
472  //shall be an algorithm ID with an OID in the set PBES2-KDFs, which for
473  //this version of PKCS #5 shall consist of id-PBKDF2
475  &pbes2Params->keyDerivationFunc);
476  //Any error to report?
477  if(error)
478  return error;
479 
480  //Point to the next field
481  data += n;
482  length -= n;
483 
484  //EncryptionScheme identifies the underlying encryption scheme. It shall be
485  //an algorithm ID with an OID in the set PBES2-Encs, whose definition is
486  //left to the application
488  &pbes2Params->encryptionScheme);
489  //Any error to report?
490  if(error)
491  return error;
492 
493  //Successful processing
494  return NO_ERROR;
495 }
496 
497 
498 /**
499  * @brief Parse KeyDerivationFunc structure
500  * @param[in] data Pointer to the ASN.1 structure to parse
501  * @param[in] length Length of the ASN.1 structure
502  * @param[out] totalLength Number of bytes that have been parsed
503  * @param[out] keyDerivationFunc Information resulting from the parsing process
504  * @return Error code
505  **/
506 
508  size_t *totalLength, Pkcs5KeyDerivationFunc *keyDerivationFunc)
509 {
510  error_t error;
511  Asn1Tag tag;
512 
513  //Read KeyDerivationFunc structure
514  error = asn1ReadSequence(data, length, &tag);
515  //Failed to decode ASN.1 tag?
516  if(error)
517  return error;
518 
519  //Save the total length of the field
520  *totalLength = tag.totalLength;
521 
522  //Point to the first field of the sequence
523  data = tag.value;
524  length = tag.length;
525 
526  //Read the KDF algorithm identifier
527  error = asn1ReadOid(data, length, &tag);
528  //Failed to decode ASN.1 tag?
529  if(error)
530  return error;
531 
532  //Save algorithm identifier
533  keyDerivationFunc->kdfAlgoId.value = tag.value;
534  keyDerivationFunc->kdfAlgoId.length = tag.length;
535 
536  //Check KDF algorithm identifier
537  if(oidComp(keyDerivationFunc->kdfAlgoId.value,
538  keyDerivationFunc->kdfAlgoId.length, PBKDF2_OID, arraysize(PBKDF2_OID)))
539  {
540  return ERROR_WRONG_IDENTIFIER;
541  }
542 
543  //Point to the next field
544  data += tag.totalLength;
545  length -= tag.totalLength;
546 
547  //Parse PBKDF2 parameters
548  error = pkcs5ParsePbkdf2Params(data, length, keyDerivationFunc);
549  //Any error to report?
550  if(error)
551  return error;
552 
553  //Successful processing
554  return NO_ERROR;
555 }
556 
557 
558 /**
559  * @brief Parse PBKDF2 parameters
560  * @param[in] data Pointer to the ASN.1 structure to parse
561  * @param[in] length Length of the ASN.1 structure
562  * @param[out] keyDerivationFunc Information resulting from the parsing process
563  * @return Error code
564  **/
565 
566 error_t pkcs5ParsePbkdf2Params(const uint8_t *data, size_t length,
567  Pkcs5KeyDerivationFunc *keyDerivationFunc)
568 {
569  error_t error;
570  int32_t value;
571  Asn1Tag tag;
572 
573  //The PBKDF2 parameters are encapsulated within a sequence
574  error = asn1ReadSequence(data, length, &tag);
575  //Failed to decode ASN.1 tag?
576  if(error)
577  return error;
578 
579  //Point to the first field of the sequence
580  data = tag.value;
581  length = tag.length;
582 
583  //The 'salt' field specifies the salt value or the source of the salt value.
584  //It shall either be an octet string or an algorithm ID with an OID in the
585  //set PBKDF2-SaltSources, which is reserved for future versions of PKCS #5
586  error = asn1ReadOctetString(data, length, &tag);
587  //Failed to decode ASN.1 tag?
588  if(error)
589  return error;
590 
591  //Save salt value
592  keyDerivationFunc->salt.value = tag.value;
593  keyDerivationFunc->salt.length = tag.length;
594 
595  //Point to the next field
596  data += tag.totalLength;
597  length -= tag.totalLength;
598 
599  //The 'iterationCount' field specifies the iteration count
600  error = asn1ReadInt32(data, length, &tag, &value);
601  //Failed to decode ASN.1 tag?
602  if(error)
603  return error;
604 
605  //The iteration count must be a positive integer
606  if(value < 0)
607  return ERROR_INVALID_SYNTAX;
608 
609  //Save iteration count
610  keyDerivationFunc->iterationCount = value;
611 
612  //Point to the next field
613  data += tag.totalLength;
614  length -= tag.totalLength;
615 
616  //The 'keyLength' field is the length in octets of the derived key
617  error = asn1ReadInt32(data, length, &tag, &value);
618 
619  //This field is optional
620  if(!error)
621  {
622  //The key length must be a positive integer
623  if(value < 0)
624  return ERROR_INVALID_SYNTAX;
625 
626  //Save key length
627  keyDerivationFunc->keyLen = value;
628 
629  //Point to the next field
630  data += tag.totalLength;
631  length -= tag.totalLength;
632  }
633  else
634  {
635  //The 'keyLength' field is no present
636  keyDerivationFunc->keyLen = 0;
637  }
638 
639  //Check whether the 'prf' field is present
640  if(length > 0)
641  {
642  //The PRF algorithm identifier is encapsulated within a sequence
643  error = asn1ReadSequence(data, length, &tag);
644  //Failed to decode ASN.1 tag?
645  if(error)
646  return error;
647 
648  //Point to the first field of the sequence
649  data = tag.value;
650  length = tag.length;
651 
652  //Read the PRF algorithm identifier
653  error = asn1ReadOid(data, length, &tag);
654  //Failed to decode ASN.1 tag?
655  if(error)
656  return error;
657 
658  //Save algorithm identifier
659  keyDerivationFunc->prfAlgoId.value = tag.value;
660  keyDerivationFunc->prfAlgoId.length = tag.length;
661  }
662  else
663  {
664  //The default pseudorandom function is HMAC-SHA-1 (refer to RFC 8018,
665  //section A.2)
666  keyDerivationFunc->prfAlgoId.value = HMAC_WITH_SHA1_OID;
667  keyDerivationFunc->prfAlgoId.length = sizeof(HMAC_WITH_SHA1_OID);
668  }
669 
670  //Successful processing
671  return NO_ERROR;
672 }
673 
674 
675 /**
676  * @brief Parse EncryptionScheme structure
677  * @param[in] data Pointer to the ASN.1 structure to parse
678  * @param[in] length Length of the ASN.1 structure
679  * @param[out] totalLength Number of bytes that have been parsed
680  * @param[out] encryptionScheme Information resulting from the parsing process
681  * @return Error code
682  **/
683 
685  size_t *totalLength, Pkcs5EncryptionScheme *encryptionScheme)
686 {
687  error_t error;
688  Asn1Tag tag;
689 
690  //Read EncryptionScheme structure
691  error = asn1ReadSequence(data, length, &tag);
692  //Failed to decode ASN.1 tag?
693  if(error)
694  return error;
695 
696  //Save the total length of the field of the sequence
697  *totalLength = tag.totalLength;
698 
699  //Point to the first field
700  data = tag.value;
701  length = tag.length;
702 
703  //Read the encryption algorithm identifier
704  error = asn1ReadOid(data, length, &tag);
705  //Failed to decode ASN.1 tag?
706  if(error)
707  return error;
708 
709  //Save algorithm identifier
710  encryptionScheme->oid.value = tag.value;
711  encryptionScheme->oid.length = tag.length;
712 
713  //Point to the next field
714  data += tag.totalLength;
715  length -= tag.totalLength;
716 
717  //The parameters field for DES-CBC-Pad, DES-EDE3-CBC-Pad and AES-CBC-Pad
718  //encryption schemes shall have type OCTET STRING specifying the
719  //initialization vector for CBC mode
720  error = asn1ReadOctetString(data, length, &tag);
721  //Failed to decode ASN.1 tag?
722  if(error)
723  return error;
724 
725  //Save initialization vector
726  encryptionScheme->iv.value = tag.value;
727  encryptionScheme->iv.length = tag.length;
728 
729  //Successful processing
730  return NO_ERROR;
731 }
732 
733 #endif
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read a 32-bit integer from the input stream.
Definition: asn1.c:285
ASN.1 (Abstract Syntax Notation One)
__weak_func error_t cbcDecrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CBC decryption.
Definition: cbc.c:108
Cipher Block Chaining (CBC) mode.
Collection of AEAD algorithms.
char char_t
Definition: compiler_port.h:48
General definitions for cryptographic algorithms.
#define cryptoAllocMem(size)
Definition: crypto.h:765
#define cryptoFreeMem(p)
Definition: crypto.h:770
Debugging facilities.
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_CIPHER_ALGO
Definition: error.h:129
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_DECRYPTION_FAILED
Definition: error.h:241
@ ERROR_UNSUPPORTED_HASH_ALGO
Definition: error.h:130
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t data[]
Definition: ethernet.h:222
const uint8_t HMAC_WITH_SHA1_OID[8]
Definition: hmac.c:55
HMAC (Keyed-Hashing for Message Authentication)
uint8_t iv[]
Definition: ike.h:1502
uint16_t totalLength
Definition: ipv4.h:292
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osStrlen(s)
Definition: os_port.h:165
#define arraysize(a)
Definition: os_port.h:71
error_t pbkdf2(const HashAlgo *hash, const uint8_t *p, size_t pLen, const uint8_t *s, size_t sLen, uint_t c, uint8_t *dk, size_t dkLen)
PBKDF2 key derivation function.
Definition: pbkdf.c:140
error_t pbkdf1(const HashAlgo *hash, const uint8_t *p, size_t pLen, const uint8_t *s, size_t sLen, uint_t c, uint8_t *dk, size_t dkLen)
PBKDF1 key derivation function.
Definition: pbkdf.c:64
const uint8_t PBKDF2_OID[9]
Definition: pbkdf.c:43
PBKDF (Password-Based Key Derivation Function)
uint_t pkcs5GetPbes2KeyLength(const uint8_t *oid, size_t length)
Get the encryption key length to be used for PBES2 operation.
Definition: pkcs5_common.c:384
const CipherAlgo * pkcs5GetPbes1CipherAlgo(const uint8_t *oid, size_t length)
Get the cipher algorithm to be used for PBES1 operation.
Definition: pkcs5_common.c:222
const CipherAlgo * pkcs5GetPbes2CipherAlgo(const uint8_t *oid, size_t length)
Get the cipher algorithm to be used for PBES2 operation.
Definition: pkcs5_common.c:285
const HashAlgo * pkcs5GetPbes2HashAlgo(const uint8_t *oid, size_t length)
Get the hash algorithm to be used for PBES2 operation.
Definition: pkcs5_common.c:135
const uint8_t PBES2_OID[9]
Definition: pkcs5_common.c:59
const HashAlgo * pkcs5GetPbes1HashAlgo(const uint8_t *oid, size_t length)
Get the hash algorithm to be used for PBES1 operation.
Definition: pkcs5_common.c:69
PKCS #5 common definitions.
error_t pkcs5DecryptPbes2(const X509AlgoId *encryptionAlgoId, const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
PBES2 decryption operation.
error_t pkcs5ParseKeyDerivationFunc(const uint8_t *data, size_t length, size_t *totalLength, Pkcs5KeyDerivationFunc *keyDerivationFunc)
Parse KeyDerivationFunc structure.
error_t pkcs5DecryptPbes1(const X509AlgoId *encryptionAlgoId, const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
PBES1 decryption operation.
error_t pkcs5ParsePbes1Params(const uint8_t *data, size_t length, Pkcs5Pbes1Params *pbes1Params)
Parse PBES1 parameters.
error_t pkcs5ParsePbkdf2Params(const uint8_t *data, size_t length, Pkcs5KeyDerivationFunc *keyDerivationFunc)
Parse PBKDF2 parameters.
error_t pkcs5ParsePbes2Params(const uint8_t *data, size_t length, Pkcs5Pbes2Params *pbes2Params)
Parse PBES2 parameters.
error_t pkcs5ParseEncryptionScheme(const uint8_t *data, size_t length, size_t *totalLength, Pkcs5EncryptionScheme *encryptionScheme)
Parse EncryptionScheme structure.
error_t pkcs5Decrypt(const X509AlgoId *encryptionAlgoId, const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
PKCS #5 decryption operation.
Definition: pkcs5_decrypt.c:61
PKCS #5 decryption routines.
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
size_t length
Definition: asn1.h:106
Common interface for encryption algorithms.
Definition: crypto.h:1036
size_t contextSize
Definition: crypto.h:1038
CipherAlgoDeinit deinit
Definition: crypto.h:1046
size_t blockSize
Definition: crypto.h:1040
CipherAlgoInit init
Definition: crypto.h:1041
Common interface for hash algorithms.
Definition: crypto.h:1014
Encryption scheme.
Definition: pkcs5_common.h:203
Pkcs5OctetString iv
Definition: pkcs5_common.h:205
Pkcs5OctetString oid
Definition: pkcs5_common.h:204
Key derivation function.
Definition: pkcs5_common.h:189
Pkcs5OctetString prfAlgoId
Definition: pkcs5_common.h:194
Pkcs5OctetString salt
Definition: pkcs5_common.h:191
Pkcs5OctetString kdfAlgoId
Definition: pkcs5_common.h:190
const uint8_t * value
Definition: pkcs5_common.h:168
PBES1 parameters.
Definition: pkcs5_common.h:178
Pkcs5OctetString salt
Definition: pkcs5_common.h:179
PBES2 parameters.
Definition: pkcs5_common.h:214
Pkcs5EncryptionScheme encryptionScheme
Definition: pkcs5_common.h:216
Pkcs5KeyDerivationFunc keyDerivationFunc
Definition: pkcs5_common.h:215
Algorithm identifier.
Definition: x509_common.h:719
X509OctetString oid
Definition: x509_common.h:720
X509OctetString params
Definition: x509_common.h:721
const uint8_t * value
Definition: x509_common.h:647
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369
Generic cipher algorithm context.