pem_common.c
Go to the documentation of this file.
1 /**
2  * @file pem_common.c
3  * @brief PEM common definitions
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/pem_common.h"
37 #include "encoding/oid.h"
38 #include "encoding/base64.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (PEM_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Convert PEM container to ASN.1 format
48  * @param[in] input PEM container to decode
49  * @param[in] inputLen Length of the PEM container to decode
50  * @param[in] label Label indicating the type of data
51  * @param[out] output ASN.1 data (optional parameter)
52  * @param[out] outputLen Length of the ASN.1 data
53  * @param[out] header PEM encapsulated header (optional parameter)
54  * @param[out] consumed Total number of characters that have been consumed
55  * (optional parameter)
56  **/
57 
58 error_t pemDecodeFile(const char_t *input, size_t inputLen, const char_t *label,
59  uint8_t *output, size_t *outputLen, PemHeader *header, size_t *consumed)
60 {
61  error_t error;
62  int_t i;
63  int_t j;
64  size_t n;
65 
66  //The PEM container begins with a "-----BEGIN " line
67  i = pemFindTag(input, inputLen, "-----BEGIN ", label, "-----");
68  //Pre-encapsulation boundary not found?
69  if(i < 0)
70  return ERROR_END_OF_FILE;
71 
72  //Skip the pre-encapsulation boundary
73  i += osStrlen("-----BEGIN -----") + osStrlen(label);
74 
75  //The PEM container ends with a "-----END " line
76  j = pemFindTag(input + i, inputLen - i, "-----END ", label, "-----");
77  //Post-encapsulation boundary not found?
78  if(j < 0)
79  return ERROR_INVALID_SYNTAX;
80 
81  //Parse PEM encapsulated header
82  error = pemParseHeader(input + i, j, header, &n);
83  //Any error to report?
84  if(error)
85  return error;
86 
87  //The contents of the PEM file is Base64-encoded
88  error = base64Decode(input + i + n, j - n, output, outputLen);
89  //Failed to decode the file?
90  if(error)
91  return error;
92 
93  //Sanity check
94  if(*outputLen == 0)
95  return ERROR_INVALID_SYNTAX;
96 
97  //The last parameter is optional
98  if(consumed != NULL)
99  {
100  //Total number of characters that have been consumed
101  *consumed = i + j + osStrlen("-----END -----") + osStrlen(label);
102  }
103 
104  //Successful processing
105  return NO_ERROR;
106 }
107 
108 
109 /**
110  * @brief Convert ASN.1 data to PEM encoding
111  * @param[in] input ASN.1 data to encode
112  * @param[in] inputLen Length of the ASN.1 data to encode
113  * @param[in] label Label indicating the type of data
114  * @param[out] output PEM container (optional parameter)
115  * @param[out] outputLen Length of the PEM container
116  **/
117 
118 error_t pemEncodeFile(const void *input, size_t inputLen, const char_t *label,
119  char_t *output, size_t *outputLen)
120 {
121  size_t n;
122  size_t labelLen;
123  char_t *p;
124 
125  //Check parameters
126  if(input == NULL || label == NULL || outputLen == NULL)
128 
129  //Calculate the length of the label
130  labelLen = osStrlen(label);
131 
132  //Generators must wrap the Base64-encoded lines so that each line consists
133  //of exactly 64 characters except for the final line, which will encode the
134  //remainder of the data (refer to RFC 7468, section 2)
135  base64EncodeMultiline(input, inputLen, output, &n, 64);
136 
137  //If the output parameter is NULL, then the function calculates the length
138  //of the resulting PEM file without copying any data
139  if(output != NULL)
140  {
141  //A PEM file starts with a pre-encapsulation boundary
142  p = output + osStrlen("-----BEGIN -----\r\n") + labelLen;
143 
144  //Make room for the pre-encapsulation boundary
145  osMemmove(p, output, n);
146 
147  //The type of data encoded is labeled depending on the type label in
148  //the "-----BEGIN " line (refer to RFC 7468, section 2)
149  osStrcpy(output, "-----BEGIN ");
150  osStrcpy(output + 11, label);
151  osMemcpy(p - 7, "-----\r\n", 7);
152 
153  //Generators must put the same label on the "-----END " line as the
154  //corresponding "-----BEGIN " line
155  osStrcpy(p + n, "\r\n-----END ");
156  osStrcpy(p + n + 11, label);
157  osStrcpy(p + n + labelLen + 11, "-----\r\n");
158  }
159 
160  //Consider the length of the PEM encapsulation boundaries
161  n += osStrlen("-----BEGIN -----\r\n") + labelLen;
162  n += osStrlen("\r\n-----END -----\r\n") + labelLen;
163 
164  //Total number of bytes that have been written
165  *outputLen = n;
166 
167  //Successful processing
168  return NO_ERROR;
169 }
170 
171 
172 /**
173  * @brief Parse PEM encapsulated header
174  * @param[in] input PEM message body
175  * @param[in] inputLen Length of the PEM message body
176  * @param[in] header PEM encapsulated header (optional parameter)
177  * @param[out] consumed Total number of bytes that have been consumed
178  * @return Error code
179  **/
180 
181 error_t pemParseHeader(const char_t *input, size_t inputLen,
182  PemHeader *header, size_t *consumed)
183 {
184  size_t n;
185  const char_t *end;
186  PemString line;
187 
188  //The header parameter is optional
189  if(header != NULL)
190  {
191  //Clear header fields
192  osMemset(header, 0, sizeof(PemHeader));
193  }
194 
195  //Total number of bytes that have been consumed
196  *consumed = 0;
197 
198  //Parse PEM encapsulated header
199  while(1)
200  {
201  //Extract a line from the PEM message body
202  end = osMemchr(input, '\n', inputLen);
203  //No end of line character detected?
204  if(end == NULL)
205  break;
206 
207  //Calculate the length of the line
208  n = end - input + 1;
209 
210  //Point to the current line
211  line.value = input;
212  line.length = n;
213 
214  //Removes all leading and trailing whitespace from a string
215  pemTrimWhitespace(&line);
216 
217  //Discard empty lines
218  if(!pemCompareString(&line, ""))
219  {
220  //Each header field consists of a field name followed by a colon,
221  //optional leading whitespace, and the field value
222  if(pemFindChar(&line, ':') >= 0)
223  {
224  //Parse header field
225  pemParseHeaderField(&line, header);
226  }
227  else
228  {
229  //We are done
230  break;
231  }
232  }
233 
234  //Point to the next line
235  input += n;
236  inputLen -= n;
237  *consumed += n;
238  }
239 
240  //Sucessful processing
241  return NO_ERROR;
242 }
243 
244 
245 /**
246  * @brief Parse header field
247  * @param[in] line Header field
248  * @param[in] header PEM encapsulated header (optional parameter)
249  **/
250 
252 {
253  PemString name;
254  PemString arg1;
255  PemString arg2;
256 
257  //Each header field consists of a field name followed by a colon,
258  //optional leading whitespace, and the field value
259  pemTokenizeString(line, ':', &name);
260 
261  //Removes all leading and trailing whitespace from the name
263 
264  //Check header field name
265  if(pemCompareString(&name, "Proc-Type"))
266  {
267  //The "Proc-Type" encapsulated header field, required for all PEM
268  //messages, identifies the type of processing performed on the
269  //transmitted message (refer to RFC 1421, section 4.6.1.1)
270  if(pemTokenizeString(line, ',', &arg1) &&
271  pemTokenizeString(line, ',', &arg2))
272  {
273  //Removes all leading and trailing whitespace characters
274  pemTrimWhitespace(&arg1);
275  pemTrimWhitespace(&arg2);
276 
277  //Save arguments
278  if(header != NULL)
279  {
280  header->procType.version = arg1;
281  header->procType.type = arg2;
282  }
283  }
284  }
285  else if(pemCompareString(&name, "DEK-Info"))
286  {
287  //The "DEK-Info" encapsulated header field identifies the message text
288  //encryption algorithm and mode, and also carries the IV used for message
289  //encryption (refer to RFC 1421, section 4.6.1.3)
290  if(pemTokenizeString(line, ',', &arg1) &&
291  pemTokenizeString(line, ',', &arg2))
292  {
293  //Removes all leading and trailing whitespace characters
294  pemTrimWhitespace(&arg1);
295  pemTrimWhitespace(&arg2);
296 
297  //Save arguments
298  if(header != NULL)
299  {
300  header->dekInfo.algo = arg1;
301  header->dekInfo.iv = arg2;
302  }
303  }
304  }
305  else
306  {
307  //Unknown header field name
308  }
309 }
310 
311 
312 /**
313  * @brief Search a string for a given tag
314  * @param[in] input String to search
315  * @param[in] inputLen Length of the string to search
316  * @param[in] tag1 First part of the tag (NULL-terminated string)
317  * @param[in] tag2 Second part of the tag (NULL-terminated string)
318  * @param[in] tag3 Third part of the tag (NULL-terminated string)
319  * @return The index of the first occurrence of the tag in the string,
320  * or -1 if the tag does not appear in the string
321  **/
322 
323 int_t pemFindTag(const char_t *input, size_t inputLen, const char_t *tag1,
324  const char_t *tag2, const char_t *tag3)
325 {
326  size_t i;
327  size_t j;
328  size_t n1;
329  size_t n2;
330  size_t n3;
331  int_t index;
332 
333  //Initialize index
334  index = -1;
335 
336  //Calculate the length of the tag
337  n1 = osStrlen(tag1);
338  n2 = osStrlen(tag2);
339  n3 = osStrlen(tag3);
340 
341  //Parse input string
342  for(i = 0; (i + n1 + n2 + n3) <= inputLen; i++)
343  {
344  //Compare current substring with the given tag
345  for(j = 0; j < (n1 + n2 + n3); j++)
346  {
347  if(j < n1)
348  {
349  if(input[i + j] != tag1[j])
350  break;
351  }
352  else if(j < (n1 + n2))
353  {
354  if(input[i + j] != tag2[j - n1])
355  break;
356  }
357  else
358  {
359  if(input[i + j] != tag3[j - n1 - n2])
360  break;
361  }
362  }
363 
364  //Check whether the tag has been found
365  if(j == (n1 + n2 + n3))
366  {
367  index = i;
368  break;
369  }
370  }
371 
372  //Return the index of the first occurrence of the tag in the string
373  return index;
374 }
375 
376 
377 /**
378  * @brief Search a string for a given character
379  * @param[in] s String to be scanned
380  * @param[in] c Character to be searched
381  * @return Index of the first occurrence of the character
382  **/
383 
385 {
386  int_t index;
387  char_t *p;
388 
389  //Search the string for the specified character
390  p = osMemchr(s->value, c, s->length);
391 
392  //Character found?
393  if(p != NULL)
394  {
395  index = p - s->value;
396  }
397  else
398  {
399  index = -1;
400  }
401 
402  //Return the index of the first occurrence of the character
403  return index;
404 }
405 
406 
407 /**
408  * @brief Compare a string against the supplied value
409  * @param[in] string String to be compared
410  * @param[in] value NULL-terminated string
411  * @return Comparison result
412  **/
413 
415 {
416  bool_t res;
417  size_t n;
418 
419  //Initialize flag
420  res = FALSE;
421 
422  //Valid NULL-terminated string?
423  if(value != NULL)
424  {
425  //Determine the length of the string
426  n = osStrlen(value);
427 
428  //Check the length of the string
429  if(string->value != NULL && string->length == n)
430  {
431  //Perform string comparison
432  if(!osStrncmp(string->value, value, n))
433  {
434  res = TRUE;
435  }
436  }
437  }
438 
439  //Return comparison result
440  return res;
441 }
442 
443 
444 /**
445  * @brief Split a string into tokens
446  * @param[in,out] s String to be split
447  * @param[in] c Delimiter character
448  * @param[out] token Resulting token
449  * @return TRUE if a token has been found, else FALSE
450  **/
451 
453 {
454  char_t *p;
455  size_t n;
456  bool_t found;
457 
458  //Search the string for the specified delimiter character
459  p = osMemchr(s->value, c, s->length);
460 
461  //Delimiter character found?
462  if(p != NULL)
463  {
464  //Retrieve the length of the token
465  n = p - s->value;
466 
467  //Extract the token from the string
468  token->value = s->value;
469  token->length = n;
470 
471  //Point to the next token
472  s->value += n + 1;
473  s->length -= n + 1;
474 
475  //A token has been found
476  found = TRUE;
477  }
478  else if(s->length > 0)
479  {
480  //This is the last token
481  token->value = s->value;
482  token->length = s->length;
483 
484  //A token has been found
485  found = TRUE;
486  }
487  else
488  {
489  //The end of the string has been reached
490  found = FALSE;
491  }
492 
493  //Return TRUE if a token has been found, else FALSE
494  return found;
495 }
496 
497 
498 /**
499  * @brief Removes all leading and trailing whitespace from a string
500  * @param[in] s String to be trimmed
501  **/
502 
504 {
505  //Trim whitespace from the beginning
506  while(s->length > 0 && osIsspace(s->value[0]))
507  {
508  s->value++;
509  s->length--;
510  }
511 
512  //Trim whitespace from the end
513  while(s->length > 0 && osIsspace(s->value[s->length - 1]))
514  {
515  s->length--;
516  }
517 }
518 
519 
520 /**
521  * @brief Get the cipher algorithm to be used for PEM encryption/decryption
522  * @param[in] algo Encryption algorithm
523  * @return Cipher algorithm
524  **/
525 
527 {
528  const CipherAlgo *cipherAlgo;
529 
530 #if (PEM_DES_SUPPORT == ENABLED && DES_SUPPORT == ENABLED)
531  //DES-CBC algorithm identifier?
532  if(pemCompareString(algo, "DES-CBC"))
533  {
534  cipherAlgo = DES_CIPHER_ALGO;
535  }
536  else
537 #endif
538 #if (PEM_3DES_SUPPORT == ENABLED && DES3_SUPPORT == ENABLED)
539  //DES-EDE3-CBC algorithm identifier?
540  if(pemCompareString(algo, "DES-EDE3-CBC"))
541  {
542  cipherAlgo = DES3_CIPHER_ALGO;
543  }
544  else
545 #endif
546 #if (PEM_AES_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
547  //AES-128-CBC algorithm identifier?
548  if(pemCompareString(algo, "AES-128-CBC"))
549  {
550  cipherAlgo = AES_CIPHER_ALGO;
551  }
552  //AES-192-CBC algorithm identifier?
553  else if(pemCompareString(algo, "AES-192-CBC"))
554  {
555  cipherAlgo = AES_CIPHER_ALGO;
556  }
557  //AES-256-CBC algorithm identifier?
558  else if(pemCompareString(algo, "AES-256-CBC"))
559  {
560  cipherAlgo = AES_CIPHER_ALGO;
561  }
562  else
563 #endif
564 #if (PEM_CAMELLIA_SUPPORT == ENABLED && CAMELLIA_SUPPORT == ENABLED)
565  //Camellia-128-CBC algorithm identifier?
566  if(pemCompareString(algo, "CAMELLIA-128-CBC"))
567  {
568  cipherAlgo = CAMELLIA_CIPHER_ALGO;
569  }
570  //Camellia-192-CBC algorithm identifier?
571  else if(pemCompareString(algo, "CAMELLIA-192-CBC"))
572  {
573  cipherAlgo = CAMELLIA_CIPHER_ALGO;
574  }
575  //Camellia-256-CBC algorithm identifier?
576  else if(pemCompareString(algo, "CAMELLIA-256-CBC"))
577  {
578  cipherAlgo = CAMELLIA_CIPHER_ALGO;
579  }
580  else
581 #endif
582 #if (PEM_ARIA_SUPPORT == ENABLED && ARIA_SUPPORT == ENABLED)
583  //ARIA-128-CBC algorithm identifier?
584  if(pemCompareString(algo, "ARIA-128-CBC"))
585  {
586  cipherAlgo = ARIA_CIPHER_ALGO;
587  }
588  //ARIA-192-CBC algorithm identifier?
589  else if(pemCompareString(algo, "ARIA-192-CBC"))
590  {
591  cipherAlgo = ARIA_CIPHER_ALGO;
592  }
593  //ARIA-256-CBC algorithm identifier?
594  else if(pemCompareString(algo, "ARIA-256-CBC"))
595  {
596  cipherAlgo = ARIA_CIPHER_ALGO;
597  }
598  else
599 #endif
600 #if (PEM_SM4_SUPPORT == ENABLED && SM4_SUPPORT == ENABLED)
601  //SM4-CBC algorithm identifier?
602  if(pemCompareString(algo, "SM4-CBC"))
603  {
604  cipherAlgo = SM4_CIPHER_ALGO;
605  }
606  else
607 #endif
608  //Unknown algorithm identifier?
609  {
610  cipherAlgo = NULL;
611  }
612 
613  //Return the cipher algorithm that matches the specified OID
614  return cipherAlgo;
615 }
616 
617 
618 /**
619  * @brief Get the encryption key length to be used for PEM encryption/decryption
620  * @param[in] algo Encryption algorithm
621  * @return Encryption key length
622  **/
623 
625 {
626  uint_t keyLen;
627 
628 #if (PEM_DES_SUPPORT == ENABLED && DES_SUPPORT == ENABLED)
629  //DES-CBC algorithm algorithm?
630  if(pemCompareString(algo, "DES-CBC"))
631  {
632  keyLen = 8;
633  }
634  else
635 #endif
636 #if (PEM_3DES_SUPPORT == ENABLED && DES3_SUPPORT == ENABLED)
637  //DES-EDE3-CBC algorithm algorithm?
638  if(pemCompareString(algo, "DES-EDE3-CBC"))
639  {
640  keyLen = 24;
641  }
642  else
643 #endif
644 #if (PEM_AES_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
645  //AES-128-CBC algorithm algorithm?
646  if(pemCompareString(algo, "AES-128-CBC"))
647  {
648  keyLen = 16;
649  }
650  //AES-192-CBC algorithm algorithm?
651  else if(pemCompareString(algo, "AES-192-CBC"))
652  {
653  keyLen = 24;
654  }
655  //AES-256-CBC algorithm algorithm?
656  else if(pemCompareString(algo, "AES-256-CBC"))
657  {
658  keyLen = 32;
659  }
660  else
661 #endif
662 #if (PEM_CAMELLIA_SUPPORT == ENABLED && CAMELLIA_SUPPORT == ENABLED)
663  //Camellia-128-CBC algorithm identifier?
664  if(pemCompareString(algo, "CAMELLIA-128-CBC"))
665  {
666  keyLen = 16;
667  }
668  //Camellia-192-CBC algorithm identifier?
669  else if(pemCompareString(algo, "CAMELLIA-192-CBC"))
670  {
671  keyLen = 24;
672  }
673  //Camellia-256-CBC algorithm identifier?
674  else if(pemCompareString(algo, "CAMELLIA-256-CBC"))
675  {
676  keyLen = 32;
677  }
678  else
679 #endif
680 #if (PEM_ARIA_SUPPORT == ENABLED && ARIA_SUPPORT == ENABLED)
681  //ARIA-128-CBC algorithm identifier?
682  if(pemCompareString(algo, "ARIA-128-CBC"))
683  {
684  keyLen = 16;
685  }
686  //ARIA-192-CBC algorithm identifier?
687  else if(pemCompareString(algo, "ARIA-192-CBC"))
688  {
689  keyLen = 24;
690  }
691  //ARIA-256-CBC algorithm identifier?
692  else if(pemCompareString(algo, "ARIA-256-CBC"))
693  {
694  keyLen = 32;
695  }
696  else
697 #endif
698 #if (PEM_SM4_SUPPORT == ENABLED && SM4_SUPPORT == ENABLED)
699  //SM4-CBC algorithm identifier?
700  if(pemCompareString(algo, "SM4-CBC"))
701  {
702  keyLen = 16;
703  }
704  else
705 #endif
706  //Unknown algorithm identifier?
707  {
708  keyLen = 0;
709  }
710 
711  //Return the encryption key length that matches the specified OID
712  return keyLen;
713 }
714 
715 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define ARIA_CIPHER_ALGO
Definition: aria.h:40
void base64EncodeMultiline(const void *input, size_t inputLen, char_t *output, size_t *outputLen, size_t lineWidth)
Base64 multiline encoding.
Definition: base64.c:79
error_t base64Decode(const char_t *input, size_t inputLen, void *output, size_t *outputLen)
Base64 decoding algorithm.
Definition: base64.c:258
Base64 encoding scheme.
#define CAMELLIA_CIPHER_ALGO
Definition: camellia.h:40
Collection of AEAD algorithms.
uint8_t token[]
Definition: coap_common.h:181
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
General definitions for cryptographic algorithms.
Debugging facilities.
#define DES3_CIPHER_ALGO
Definition: des3.h:46
#define DES_CIPHER_ALGO
Definition: des.h:45
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_END_OF_FILE
Definition: error.h:159
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t c
Definition: ndp.h:514
uint8_t s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
OID (Object Identifier)
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemmove(dest, src, length)
Definition: os_port.h:147
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osStrlen(s)
Definition: os_port.h:165
#define osStrncmp(s1, s2, length)
Definition: os_port.h:177
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define osStrcpy(s1, s2)
Definition: os_port.h:207
#define osIsspace(c)
Definition: os_port.h:285
#define osMemchr(p, c, length)
Definition: os_port.h:159
error_t pemDecodeFile(const char_t *input, size_t inputLen, const char_t *label, uint8_t *output, size_t *outputLen, PemHeader *header, size_t *consumed)
Convert PEM container to ASN.1 format.
Definition: pem_common.c:58
error_t pemEncodeFile(const void *input, size_t inputLen, const char_t *label, char_t *output, size_t *outputLen)
Convert ASN.1 data to PEM encoding.
Definition: pem_common.c:118
uint_t pemGetKeyLength(const PemString *algo)
Get the encryption key length to be used for PEM encryption/decryption.
Definition: pem_common.c:624
bool_t pemTokenizeString(PemString *s, char_t c, PemString *token)
Split a string into tokens.
Definition: pem_common.c:452
void pemParseHeaderField(PemString *line, PemHeader *header)
Parse header field.
Definition: pem_common.c:251
int_t pemFindTag(const char_t *input, size_t inputLen, const char_t *tag1, const char_t *tag2, const char_t *tag3)
Search a string for a given tag.
Definition: pem_common.c:323
void pemTrimWhitespace(PemString *s)
Removes all leading and trailing whitespace from a string.
Definition: pem_common.c:503
const CipherAlgo * pemGetCipherAlgo(const PemString *algo)
Get the cipher algorithm to be used for PEM encryption/decryption.
Definition: pem_common.c:526
int_t pemFindChar(const PemString *s, char_t c)
Search a string for a given character.
Definition: pem_common.c:384
bool_t pemCompareString(const PemString *string, const char_t *value)
Compare a string against the supplied value.
Definition: pem_common.c:414
error_t pemParseHeader(const char_t *input, size_t inputLen, PemHeader *header, size_t *consumed)
Parse PEM encapsulated header.
Definition: pem_common.c:181
PEM common definitions.
const uint8_t res[]
char_t name[]
#define SM4_CIPHER_ALGO
Definition: sm4.h:45
Common interface for encryption algorithms.
Definition: crypto.h:1036
PemString algo
Definition: pem_common.h:120
PemString iv
Definition: pem_common.h:121
PEM encapsulated header.
Definition: pem_common.h:130
PemProcType procType
Definition: pem_common.h:131
PemDekInfo dekInfo
Definition: pem_common.h:132
PemString version
Definition: pem_common.h:109
PemString type
Definition: pem_common.h:110
String representation.
Definition: pem_common.h:97
const char_t * value
Definition: pem_common.h:98
size_t length
Definition: pem_common.h:99
uint8_t value[]
Definition: tcp.h:369