aircampro

encode / decode asn1 utf cipher

Jul 9th, 2021
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 100.10 KB | None | 0 0
  1. /**
  2.  * @file encoders.c
  3.  * @brief Radix64 encoding scheme
  4.  *
  5.  * @section License
  6.  *
  7.  * SPDX-License-Identifier: GPL-2.0-or-later
  8.  *
  9.  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
  10.  * Ported by Copyright (C) 2020 A C P Avaiation
  11.  *
  12.  * This file is part of CycloneCrypto Open.
  13.  *
  14.  * This program is free software; you can redistribute it and/or
  15.  * modify it under the terms of the GNU General Public License
  16.  * as published by the Free Software Foundation; either version 2
  17.  * of the License, or (at your option) any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; if not, write to the Free Software Foundation,
  26.  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  27.  *
  28.  * @author Oryx Embedded SARL (www.oryx-embedded.com)
  29.  * @version 1.9.6
  30.  **/
  31.  
  32. #define TRACE_LEVEL CRYPTO_TRACE_LEVEL                                          //Switch to the appropriate trace level
  33.  
  34. //Dependencies
  35. //#include "core/crypto.h"
  36. #include "definitions.h"
  37. #include "encoders.h"
  38.  
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif /* __cplusplus */
  42.  
  43. void radix64Encode(const void *inputV, size_t inputLen, char_t *outputV, size_t *outputLen);   //Radix64 encoding related functions
  44. error_t radix64Decode(const char_t *input, size_t inputLen, void *outputV, size_t *outputLen);
  45. void base64Encode(const void *input, size_t inputLen, char_t *output, size_t *outputLen);     //Base64 encoding related functions
  46. error_t base64Decode(const char_t *input, size_t inputLen, void *output,size_t *outputLen);
  47. void base64urlEncode(const void *input, size_t inputLen, char_t *output, size_t *outputLen);  //Base64url encoding related functions
  48. error_t base64urlDecode(const char_t *input, size_t inputLen, void *output, size_t *outputLen);
  49. error_t asn1ReadTag(const uint8_t *dataV, size_t length, Asn1Tag *tag);                      //ASN.1 related functions      
  50. error_t asn1ReadSequence(const uint8_t *dataV, size_t length, Asn1Tag *tag);
  51. error_t asn1ReadOctetString(const uint8_t *dataV, size_t length, Asn1Tag *tag);
  52. error_t asn1ReadOid(const uint8_t *dataV, size_t length, Asn1Tag *tag);
  53. error_t asn1ReadBoolean(const uint8_t *dataV, size_t length, Asn1Tag *tag, bool_t *value);
  54. error_t asn1ReadInt32(const uint8_t *dataV, size_t length, Asn1Tag *tag, int32_t *value);
  55. error_t mpiGrow(Mpi *r, uint8_t size);
  56. error_t asn1ReadMpi(const uint8_t *dataV, size_t length, Asn1Tag *tag, Mpi *value);
  57. error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *dataV, size_t *written);
  58. error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *dataV,size_t *written);
  59. uint8_t mpiGetBitLength(const Mpi *a);
  60. uint8_t mpiGetByteLength(const Mpi *a);
  61. error_t mpiExport(const Mpi *a, uint8_t *dataV, uint8_t length, MpiFormat format);
  62. error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *dataV, size_t *written);
  63. error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType);
  64. error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length);
  65. error_t asn1DumpObject(const uint8_t *dataV, size_t length, uint_t level);
  66. int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2);
  67. void ConvertWiegand(char* CodBinLeitura, char* CartaoWiegand );                 //weigand
  68. uint32_t zigzagEncode(int32_t value);                                           //zigzag
  69. int16_t huffmanEncodeBufStreaming(huffmanState_t *state, const uint8_t *inBuf, int16_t inLen, const huffmanTable_t *huffmanTable);  //huffman
  70. int16_t huffmanEncodeBuf(uint8_t *outBuf, int16_t outBufLen, const uint8_t *inBuf, int16_t inLen, const huffmanTable_t *huffmanTable);
  71. int16_t utf8_encode(int32_t codepoint, char *buffer, size_t *size);             //utf8
  72. size_t utf8_check_first(char byte);
  73. size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint);
  74. const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint);
  75. int16_t utf8_check_string(const char *string, size_t length);
  76. int16_t encode_utf8(uint8_t  *out, uint32_t in);
  77. int16_t decode_utf8(uint32_t *out, const uint8_t *in);
  78. int16_t decode_utf16(uint32_t *out, const uint16_t *in);                        //utf16
  79. int16_t encode_utf16(uint16_t *out, uint32_t in);
  80. size_t utf16_to_utf32(uint32_t  *out, const uint16_t *in, size_t len);          //utf conversion
  81. size_t utf16_to_utf8(uint8_t *out, const uint16_t *in, size_t len);
  82. size_t utf32_to_utf16(uint16_t *out, const uint32_t *in,  size_t len);
  83. size_t utf32_to_utf8(uint8_t *out, const uint32_t *in, size_t len);
  84. size_t utf8_to_utf16(uint16_t *out, const uint8_t *in, size_t len);
  85. size_t utf8_to_utf32(uint32_t *out, const uint8_t *in, size_t len);
  86. void vigenersCipherEncode( char* cipherText, char* keyword, char* message  );   //vigeners
  87. void vigenersCipherDecode( char* cipherText, char* keyword, char* message  );
  88. void rot13CipherEncode( char* cipherText, char* keyword, char* message  );      //rot13
  89. void rot13CipherDecode( char* cipherText, char* keyword, char* message  );
  90.  
  91. const huffmanTable_t huffmanTable[HUFFMAN_TABLE_SIZE] = {
  92. //   Len    Code       Char Bitcode
  93.     {  2, 0xC000u }, // 0x00 11
  94.     {  3, 0xA000u }, // 0x01 101
  95.     {  4, 0x9000u }, // 0x02 1001
  96.     {  5, 0x8800u }, // 0x03 10001
  97.     {  5, 0x8000u }, // 0x04 10000
  98.     {  6, 0x7400u }, // 0x05 011101
  99.     {  6, 0x7000u }, // 0x06 011100
  100.     {  6, 0x6C00u }, // 0x07 011011
  101.     {  6, 0x6800u }, // 0x08 011010
  102.     {  7, 0x6200u }, // 0x09 0110001
  103.     {  7, 0x6000u }, // 0x0A 0110000
  104.     {  7, 0x5E00u }, // 0x0B 0101111
  105.     {  7, 0x5C00u }, // 0x0C 0101110
  106.     {  7, 0x5A00u }, // 0x0D 0101101
  107.     {  7, 0x5800u }, // 0x0E 0101100
  108.     {  7, 0x5600u }, // 0x0F 0101011
  109.     {  6, 0x6400u }, // 0x10 011001
  110.     {  7, 0x5400u }, // 0x11 0101010
  111.     {  7, 0x5200u }, // 0x12 0101001
  112.     {  8, 0x5100u }, // 0x13 01010001
  113.     {  8, 0x5000u }, // 0x14 01010000
  114.     {  8, 0x4F00u }, // 0x15 01001111
  115.     {  8, 0x4E00u }, // 0x16 01001110
  116.     {  8, 0x4D00u }, // 0x17 01001101
  117.     {  8, 0x4C00u }, // 0x18 01001100
  118.     {  8, 0x4B00u }, // 0x19 01001011
  119.     {  8, 0x4A00u }, // 0x1A 01001010
  120.     {  8, 0x4900u }, // 0x1B 01001001
  121.     {  8, 0x4800u }, // 0x1C 01001000
  122.     {  8, 0x4700u }, // 0x1D 01000111
  123.     {  8, 0x4600u }, // 0x1E 01000110
  124.     {  8, 0x4500u }, // 0x1F 01000101
  125.     {  8, 0x4400u }, // 0x20 01000100
  126.     {  8, 0x4300u }, // 0x21 01000011
  127.     {  8, 0x4200u }, // 0x22 01000010
  128.     {  8, 0x4100u }, // 0x23 01000001
  129.     {  8, 0x4000u }, // 0x24 01000000
  130.     {  9, 0x3C80u }, // 0x25 001111001
  131.     {  9, 0x3C00u }, // 0x26 001111000
  132.     {  9, 0x3B80u }, // 0x27 001110111
  133.     {  9, 0x3B00u }, // 0x28 001110110
  134.     {  9, 0x3A80u }, // 0x29 001110101
  135.     {  9, 0x3A00u }, // 0x2A 001110100
  136.     {  9, 0x3980u }, // 0x2B 001110011
  137.     {  9, 0x3900u }, // 0x2C 001110010
  138.     {  9, 0x3880u }, // 0x2D 001110001
  139.     {  9, 0x3800u }, // 0x2E 001110000
  140.     {  9, 0x3780u }, // 0x2F 001101111
  141.     {  8, 0x3F00u }, // 0x30 00111111
  142.     {  9, 0x3700u }, // 0x31 001101110
  143.     {  9, 0x3680u }, // 0x32 001101101
  144.     {  9, 0x3600u }, // 0x33 001101100
  145.     {  9, 0x3580u }, // 0x34 001101011
  146.     {  9, 0x3500u }, // 0x35 001101010
  147.     {  9, 0x3480u }, // 0x36 001101001
  148.     {  9, 0x3400u }, // 0x37 001101000
  149.     {  9, 0x3380u }, // 0x38 001100111
  150.     {  9, 0x3300u }, // 0x39 001100110
  151.     {  9, 0x3280u }, // 0x3A 001100101
  152.     {  9, 0x3200u }, // 0x3B 001100100
  153.     {  9, 0x3180u }, // 0x3C 001100011
  154.     {  9, 0x3100u }, // 0x3D 001100010
  155.     {  9, 0x3080u }, // 0x3E 001100001
  156.     {  9, 0x3000u }, // 0x3F 001100000
  157.     {  8, 0x3E00u }, // 0x40 00111110
  158.     {  9, 0x2F80u }, // 0x41 001011111
  159.     {  9, 0x2F00u }, // 0x42 001011110
  160.     {  9, 0x2E80u }, // 0x43 001011101
  161.     {  9, 0x2E00u }, // 0x44 001011100
  162.     {  9, 0x2D80u }, // 0x45 001011011
  163.     {  9, 0x2D00u }, // 0x46 001011010
  164.     {  9, 0x2C80u }, // 0x47 001011001
  165.     {  9, 0x2C00u }, // 0x48 001011000
  166.     {  9, 0x2B80u }, // 0x49 001010111
  167.     { 10, 0x27C0u }, // 0x4A 0010011111
  168.     { 10, 0x2780u }, // 0x4B 0010011110
  169.     {  9, 0x2B00u }, // 0x4C 001010110
  170.     { 10, 0x2740u }, // 0x4D 0010011101
  171.     { 10, 0x2700u }, // 0x4E 0010011100
  172.     {  9, 0x2A80u }, // 0x4F 001010101
  173.     {  5, 0x7800u }, // 0x50 01111
  174.     {  9, 0x2A00u }, // 0x51 001010100
  175.     { 10, 0x26C0u }, // 0x52 0010011011
  176.     { 10, 0x2680u }, // 0x53 0010011010
  177.     { 10, 0x2640u }, // 0x54 0010011001
  178.     { 10, 0x2600u }, // 0x55 0010011000
  179.     { 10, 0x25C0u }, // 0x56 0010010111
  180.     { 10, 0x2580u }, // 0x57 0010010110
  181.     { 10, 0x2540u }, // 0x58 0010010101
  182.     { 10, 0x2500u }, // 0x59 0010010100
  183.     { 10, 0x24C0u }, // 0x5A 0010010011
  184.     { 10, 0x2480u }, // 0x5B 0010010010
  185.     { 10, 0x2440u }, // 0x5C 0010010001
  186.     { 10, 0x2400u }, // 0x5D 0010010000
  187.     { 10, 0x23C0u }, // 0x5E 0010001111
  188.     { 10, 0x2380u }, // 0x5F 0010001110
  189.     { 10, 0x2340u }, // 0x60 0010001101
  190.     { 10, 0x2300u }, // 0x61 0010001100
  191.     { 10, 0x22C0u }, // 0x62 0010001011
  192.     { 10, 0x2280u }, // 0x63 0010001010
  193.     { 10, 0x2240u }, // 0x64 0010001001
  194.     { 10, 0x2200u }, // 0x65 0010001000
  195.     { 10, 0x21C0u }, // 0x66 0010000111
  196.     { 10, 0x2180u }, // 0x67 0010000110
  197.     { 10, 0x2140u }, // 0x68 0010000101
  198.     { 10, 0x2100u }, // 0x69 0010000100
  199.     { 10, 0x20C0u }, // 0x6A 0010000011
  200.     { 10, 0x2080u }, // 0x6B 0010000010
  201.     { 10, 0x2040u }, // 0x6C 0010000001
  202.     { 10, 0x2000u }, // 0x6D 0010000000
  203.     { 10, 0x1FC0u }, // 0x6E 0001111111
  204.     { 10, 0x1F80u }, // 0x6F 0001111110
  205.     { 10, 0x1F40u }, // 0x70 0001111101
  206.     { 10, 0x1F00u }, // 0x71 0001111100
  207.     { 10, 0x1EC0u }, // 0x72 0001111011
  208.     { 10, 0x1E80u }, // 0x73 0001111010
  209.     { 10, 0x1E40u }, // 0x74 0001111001
  210.     { 10, 0x1E00u }, // 0x75 0001111000
  211.     { 10, 0x1DC0u }, // 0x76 0001110111
  212.     { 10, 0x1D80u }, // 0x77 0001110110
  213.     { 10, 0x1D40u }, // 0x78 0001110101
  214.     { 10, 0x1D00u }, // 0x79 0001110100
  215.     { 10, 0x1CC0u }, // 0x7A 0001110011
  216.     { 10, 0x1C80u }, // 0x7B 0001110010
  217.     { 10, 0x1C40u }, // 0x7C 0001110001
  218.     { 10, 0x1C00u }, // 0x7D 0001110000
  219.     { 10, 0x1BC0u }, // 0x7E 0001101111
  220.     { 10, 0x1B80u }, // 0x7F 0001101110
  221.     {  9, 0x2980u }, // 0x80 001010011
  222.     { 10, 0x1B40u }, // 0x81 0001101101
  223.     { 10, 0x1B00u }, // 0x82 0001101100
  224.     { 10, 0x1AC0u }, // 0x83 0001101011
  225.     { 10, 0x1A80u }, // 0x84 0001101010
  226.     { 10, 0x1A40u }, // 0x85 0001101001
  227.     { 10, 0x1A00u }, // 0x86 0001101000
  228.     { 10, 0x19C0u }, // 0x87 0001100111
  229.     { 10, 0x1980u }, // 0x88 0001100110
  230.     { 10, 0x1940u }, // 0x89 0001100101
  231.     { 10, 0x1900u }, // 0x8A 0001100100
  232.     { 10, 0x18C0u }, // 0x8B 0001100011
  233.     { 10, 0x1880u }, // 0x8C 0001100010
  234.     { 10, 0x1840u }, // 0x8D 0001100001
  235.     { 10, 0x1800u }, // 0x8E 0001100000
  236.     { 10, 0x17C0u }, // 0x8F 0001011111
  237.     { 10, 0x1780u }, // 0x90 0001011110
  238.     { 10, 0x1740u }, // 0x91 0001011101
  239.     { 10, 0x1700u }, // 0x92 0001011100
  240.     { 10, 0x16C0u }, // 0x93 0001011011
  241.     { 10, 0x1680u }, // 0x94 0001011010
  242.     { 10, 0x1640u }, // 0x95 0001011001
  243.     { 10, 0x1600u }, // 0x96 0001011000
  244.     { 10, 0x15C0u }, // 0x97 0001010111
  245.     { 10, 0x1580u }, // 0x98 0001010110
  246.     { 10, 0x1540u }, // 0x99 0001010101
  247.     { 10, 0x1500u }, // 0x9A 0001010100
  248.     { 10, 0x14C0u }, // 0x9B 0001010011
  249.     { 10, 0x1480u }, // 0x9C 0001010010
  250.     { 10, 0x1440u }, // 0x9D 0001010001
  251.     { 10, 0x1400u }, // 0x9E 0001010000
  252.     { 10, 0x13C0u }, // 0x9F 0001001111
  253.     { 10, 0x1380u }, // 0xA0 0001001110
  254.     { 10, 0x1340u }, // 0xA1 0001001101
  255.     { 10, 0x1300u }, // 0xA2 0001001100
  256.     { 10, 0x12C0u }, // 0xA3 0001001011
  257.     { 10, 0x1280u }, // 0xA4 0001001010
  258.     { 10, 0x1240u }, // 0xA5 0001001001
  259.     { 10, 0x1200u }, // 0xA6 0001001000
  260.     { 10, 0x11C0u }, // 0xA7 0001000111
  261.     { 10, 0x1180u }, // 0xA8 0001000110
  262.     { 10, 0x1140u }, // 0xA9 0001000101
  263.     { 10, 0x1100u }, // 0xAA 0001000100
  264.     { 10, 0x10C0u }, // 0xAB 0001000011
  265.     { 10, 0x1080u }, // 0xAC 0001000010
  266.     { 10, 0x1040u }, // 0xAD 0001000001
  267.     { 10, 0x1000u }, // 0xAE 0001000000
  268.     { 10, 0x0FC0u }, // 0xAF 0000111111
  269.     { 10, 0x0F80u }, // 0xB0 0000111110
  270.     { 10, 0x0F40u }, // 0xB1 0000111101
  271.     { 10, 0x0F00u }, // 0xB2 0000111100
  272.     { 10, 0x0EC0u }, // 0xB3 0000111011
  273.     { 10, 0x0E80u }, // 0xB4 0000111010
  274.     { 10, 0x0E40u }, // 0xB5 0000111001
  275.     { 10, 0x0E00u }, // 0xB6 0000111000
  276.     { 10, 0x0DC0u }, // 0xB7 0000110111
  277.     { 10, 0x0D80u }, // 0xB8 0000110110
  278.     { 10, 0x0D40u }, // 0xB9 0000110101
  279.     { 10, 0x0D00u }, // 0xBA 0000110100
  280.     { 10, 0x0CC0u }, // 0xBB 0000110011
  281.     { 10, 0x0C80u }, // 0xBC 0000110010
  282.     { 10, 0x0C40u }, // 0xBD 0000110001
  283.     { 10, 0x0C00u }, // 0xBE 0000110000
  284.     { 10, 0x0BC0u }, // 0xBF 0000101111
  285.     { 10, 0x0B80u }, // 0xC0 0000101110
  286.     { 10, 0x0B40u }, // 0xC1 0000101101
  287.     { 10, 0x0B00u }, // 0xC2 0000101100
  288.     { 10, 0x0AC0u }, // 0xC3 0000101011
  289.     { 10, 0x0A80u }, // 0xC4 0000101010
  290.     { 10, 0x0A40u }, // 0xC5 0000101001
  291.     { 10, 0x0A00u }, // 0xC6 0000101000
  292.     { 10, 0x09C0u }, // 0xC7 0000100111
  293.     { 10, 0x0980u }, // 0xC8 0000100110
  294.     { 10, 0x0940u }, // 0xC9 0000100101
  295.     { 10, 0x0900u }, // 0xCA 0000100100
  296.     { 10, 0x08C0u }, // 0xCB 0000100011
  297.     { 10, 0x0880u }, // 0xCC 0000100010
  298.     { 10, 0x0840u }, // 0xCD 0000100001
  299.     { 10, 0x0800u }, // 0xCE 0000100000
  300.     { 10, 0x07C0u }, // 0xCF 0000011111
  301.     { 10, 0x0780u }, // 0xD0 0000011110
  302.     { 10, 0x0740u }, // 0xD1 0000011101
  303.     { 10, 0x0700u }, // 0xD2 0000011100
  304.     { 10, 0x06C0u }, // 0xD3 0000011011
  305.     { 10, 0x0680u }, // 0xD4 0000011010
  306.     { 11, 0x0320u }, // 0xD5 00000011001
  307.     { 10, 0x0640u }, // 0xD6 0000011001
  308.     { 10, 0x0600u }, // 0xD7 0000011000
  309.     { 10, 0x05C0u }, // 0xD8 0000010111
  310.     { 10, 0x0580u }, // 0xD9 0000010110
  311.     { 10, 0x0540u }, // 0xDA 0000010101
  312.     { 10, 0x0500u }, // 0xDB 0000010100
  313.     { 10, 0x04C0u }, // 0xDC 0000010011
  314.     { 11, 0x0300u }, // 0xDD 00000011000
  315.     { 10, 0x0480u }, // 0xDE 0000010010
  316.     { 10, 0x0440u }, // 0xDF 0000010001
  317.     {  9, 0x2900u }, // 0xE0 001010010
  318.     { 10, 0x0400u }, // 0xE1 0000010000
  319.     { 10, 0x03C0u }, // 0xE2 0000001111
  320.     { 11, 0x02E0u }, // 0xE3 00000010111
  321.     { 10, 0x0380u }, // 0xE4 0000001110
  322.     { 11, 0x02C0u }, // 0xE5 00000010110
  323.     { 11, 0x02A0u }, // 0xE6 00000010101
  324.     { 11, 0x0280u }, // 0xE7 00000010100
  325.     { 11, 0x0260u }, // 0xE8 00000010011
  326.     { 11, 0x0240u }, // 0xE9 00000010010
  327.     { 11, 0x0220u }, // 0xEA 00000010001
  328.     { 11, 0x0200u }, // 0xEB 00000010000
  329.     { 11, 0x01E0u }, // 0xEC 00000001111
  330.     { 11, 0x01C0u }, // 0xED 00000001110
  331.     { 11, 0x01A0u }, // 0xEE 00000001101
  332.     { 10, 0x0340u }, // 0xEF 0000001101
  333.     {  8, 0x3D00u }, // 0xF0 00111101
  334.     {  9, 0x2880u }, // 0xF1 001010001
  335.     { 11, 0x0180u }, // 0xF2 00000001100
  336.     { 11, 0x0160u }, // 0xF3 00000001011
  337.     { 11, 0x0140u }, // 0xF4 00000001010
  338.     { 11, 0x0120u }, // 0xF5 00000001001
  339.     { 11, 0x0100u }, // 0xF6 00000001000
  340.     { 11, 0x00E0u }, // 0xF7 00000000111
  341.     { 11, 0x00C0u }, // 0xF8 00000000110
  342.     { 12, 0x0010u }, // 0xF9 000000000001
  343.     { 11, 0x00A0u }, // 0xFA 00000000101
  344.     { 11, 0x0080u }, // 0xFB 00000000100
  345.     { 11, 0x0060u }, // 0xFC 00000000011
  346.     { 11, 0x0040u }, // 0xFD 00000000010
  347.     { 11, 0x0020u }, // 0xFE 00000000001
  348.     {  9, 0x2800u }, // 0xFF 001010000
  349.     { 12, 0x0000u }, // EOF  000000000000
  350. };
  351.  
  352. #if (RADIX64_SUPPORT == ENABLED)                                                //Check crypto library configuration
  353.  
  354. //Radix64 encoding table
  355. static const char_t radix64EncTable[64] =
  356. {
  357.    '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  358.    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  359.    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  360.    'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
  361. };
  362.  
  363. //Radix64 decoding table
  364. static const uint8_t radix64DecTable[128] =
  365. {
  366.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  367.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  368.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
  369.    0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  370.    0xFF, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
  371.    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  372.    0xFF, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
  373.    0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  374. };
  375. #endif
  376.  
  377.  
  378. #if (BASE64_SUPPORT == ENABLED)                                                 //Check crypto library configuration
  379.  
  380. //Base64 encoding table
  381. static const char_t base64EncTable[64] =
  382. {
  383.    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  384.    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  385.    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  386.    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
  387. };
  388.  
  389. //Base64 decoding table
  390. static const uint8_t base64DecTable[128] =
  391. {
  392.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  393.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  394.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
  395.    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  396.    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
  397.    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  398.    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  399.    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  400. };
  401. #endif
  402. //Check crypto library configuration
  403. #if (BASE64URL_SUPPORT == ENABLED)
  404. //Base64url encoding table
  405. static const char_t base64urlEncTable[64] =
  406. {
  407.    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  408.    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  409.    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  410.    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
  411. };
  412.  
  413. //Base64url decoding table
  414. static const uint8_t base64urlDecTable[128] =
  415. {
  416.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  417.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  418.    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF,
  419.    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  420.    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
  421.    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
  422.    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  423.    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  424. };
  425. #endif
  426. #if (RADIX64_SUPPORT == ENABLED)
  427. /**
  428.  * @brief Radix64 encoding algorithm
  429.  * @param[in] input Input data to encode
  430.  * @param[in] inputLen Length of the data to encode
  431.  * @param[out] output NULL-terminated string encoded with Radix64 algorithm
  432.  * @param[out] outputLen Length of the encoded string (optional parameter)
  433.  **/
  434. void radix64Encode(const void *inputV, size_t inputLen, char_t *outputV, size_t *outputLen)
  435. {
  436.    size_t n;
  437.    uint8_t a;
  438.    uint8_t b;
  439.    uint8_t c;
  440.    uint8_t d;
  441.    const uint8_t *p;
  442.  
  443.    //Point to the first byte of the input data
  444.    p = (const uint8_t *) inputV;
  445.  
  446.    //Divide the input stream into blocks of 3 bytes
  447.    n = inputLen / 3;
  448.  
  449.    //A full encoding quantum is always completed at the end of a quantity
  450.    if(inputLen == (n * 3 + 1))
  451.    {
  452.       //The final quantum of encoding input is exactly 8 bits
  453.       if(inputV != NULL && outputV != NULL)
  454.       {
  455.          //Read input data
  456.          a = (p[n * 3] & 0xFC) >> 2;
  457.          b = (p[n * 3] & 0x03) << 4;
  458.  
  459.          //The final unit of encoded output will be two characters
  460.          outputV[n * 4] = radix64EncTable[a];
  461.          outputV[n * 4 + 1] = radix64EncTable[b];
  462.          outputV[n * 4 + 2] = '\0';
  463.       }
  464.  
  465.       //Length of the encoded string (excluding the terminating NULL)
  466.       if(outputLen != NULL)
  467.       {
  468.          *outputLen = n * 4 + 2;
  469.       }
  470.    }
  471.    else if(inputLen == (n * 3 + 2))
  472.    {
  473.       //The final quantum of encoding input is exactly 16 bits
  474.       if(inputV != NULL && outputV != NULL)
  475.       {
  476.          //Read input data
  477.          a = (p[n * 3] & 0xFC) >> 2;
  478.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  479.          c = (p[n * 3 + 1] & 0x0F) << 2;
  480.  
  481.          //The final unit of encoded output will be three characters followed
  482.          //by one "=" padding character
  483.          outputV[n * 4] = radix64EncTable[a];
  484.          outputV[n * 4 + 1] = radix64EncTable[b];
  485.          outputV[n * 4 + 2] = radix64EncTable[c];
  486.          outputV[n * 4 + 3] = '\0';
  487.       }
  488.  
  489.       //Length of the encoded string (excluding the terminating NULL)
  490.       if(outputLen != NULL)
  491.       {
  492.          *outputLen = n * 4 + 3;
  493.       }
  494.    }
  495.    else
  496.    {
  497.       //The final quantum of encoding input is an integral multiple of 24 bits
  498.       if(outputV != NULL)
  499.       {
  500.          //The final unit of encoded output will be an integral multiple of 4
  501.          //characters
  502.          outputV[n * 4] = '\0';
  503.       }
  504.  
  505.       //Length of the encoded string (excluding the terminating NULL)
  506.       if(outputLen != NULL)
  507.       {
  508.          *outputLen = n * 4;
  509.       }
  510.    }
  511.  
  512.    //If the output parameter is NULL, then the function calculates the
  513.    //length of the resulting Radix64 string without copying any data
  514.    if(inputV != NULL && outputV != NULL)
  515.    {
  516.       //The input data is processed block by block
  517.       while(n-- > 0)
  518.       {
  519.          //Read input data
  520.          a = (p[n * 3] & 0xFC) >> 2;
  521.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  522.          c = ((p[n * 3 + 1] & 0x0F) << 2) | ((p[n * 3 + 2] & 0xC0) >> 6);
  523.          d = p[n * 3 + 2] & 0x3F;
  524.  
  525.          //Map each 3-byte block to 4 printable characters using the Radix64
  526.          //character set
  527.          outputV[n * 4] = radix64EncTable[a];
  528.          outputV[n * 4 + 1] = radix64EncTable[b];
  529.          outputV[n * 4 + 2] = radix64EncTable[c];
  530.          outputV[n * 4 + 3] = radix64EncTable[d];
  531.       }
  532.    }
  533. }
  534.  
  535. /**
  536.  * @brief Radix64 decoding algorithm
  537.  * @param[in] input Radix64-encoded string
  538.  * @param[in] inputLen Length of the encoded string
  539.  * @param[out] output Resulting decoded data
  540.  * @param[out] outputLen Length of the decoded data
  541.  * @return Error code
  542.  **/
  543. error_t radix64Decode(const char_t *inputV, size_t inputLen, void *output, size_t *outputLen)
  544. {
  545.    error_t error;
  546.    uint32_t value;
  547.    uint_t c;
  548.    size_t i;
  549.    size_t n;
  550.    uint8_t *p;
  551.  
  552.    //Check parameters
  553.    if(inputV == NULL && inputLen != 0)
  554.       return ERROR_INVALID_PARAMETER;
  555.    if(outputLen == NULL)
  556.       return ERROR_INVALID_PARAMETER;
  557.  
  558.    //Check the length of the input string
  559.    if((inputLen % 4) == 1)
  560.       return ERROR_INVALID_LENGTH;
  561.  
  562.    //Initialize status code
  563.    error = NO_ERROR;
  564.  
  565.    //Point to the buffer where to write the decoded data
  566.    p = (uint8_t *) output;
  567.  
  568.    //Initialize variables
  569.    n = 0;
  570.    value = 0;
  571.  
  572.    //Process the Radix64-encoded string
  573.    for(i = 0; i < inputLen && !error; i++)
  574.    {
  575.       //Get current character
  576.       c = (uint_t) inputV[i];
  577.  
  578.       //Check the value of the current character
  579.       if(c < 128 && radix64DecTable[c] < 64)
  580.       {
  581.          //Decode the current character
  582.          value = (value << 6) | radix64DecTable[c];
  583.  
  584.          //Divide the input stream into blocks of 4 characters
  585.          if((i % 4) == 3)
  586.          {
  587.             //Map each 4-character block to 3 bytes
  588.             if(p != NULL)
  589.             {
  590.                p[n] = (value >> 16) & 0xFF;
  591.                p[n + 1] = (value >> 8) & 0xFF;
  592.                p[n + 2] = value & 0xFF;
  593.             }
  594.  
  595.             //Adjust the length of the decoded data
  596.             n += 3;
  597.             //Decode next block
  598.             value = 0;
  599.          }
  600.       }
  601.       else
  602.       {
  603.          //Implementations must reject the encoded data if it contains
  604.          //characters outside the base alphabet
  605.          error = ERROR_INVALID_CHARACTER;
  606.       }
  607.    }
  608.  
  609.    //Check status code
  610.    if(!error)
  611.    {
  612.       //All trailing pad characters are omitted in Radix64
  613.       if((inputLen % 4) == 2)
  614.       {
  615.          //The last block contains only 1 byte
  616.          if(p != NULL)
  617.          {
  618.             //Decode the last byte
  619.             p[n] = (value >> 4) & 0xFF;
  620.          }
  621.  
  622.          //Adjust the length of the decoded data
  623.          n++;
  624.       }
  625.       else if((inputLen % 4) == 3)
  626.       {
  627.          //The last block contains only 2 bytes
  628.          if(p != NULL)
  629.          {
  630.             //Decode the last two bytes
  631.             p[n] = (value >> 10) & 0xFF;
  632.             p[n + 1] = (value >> 2) & 0xFF;
  633.          }
  634.  
  635.          //Adjust the length of the decoded data
  636.          n += 2;
  637.       }
  638.       else
  639.       {
  640.          //No pad characters in this case
  641.       }
  642.    }
  643.  
  644.    //Total number of bytes that have been written
  645.    *outputLen = n;
  646.  
  647.    //Return status code
  648.    return error;
  649. }
  650.  
  651. #endif
  652. //Check crypto library configuration
  653. #if (BASE64_SUPPORT == ENABLED)
  654. /**
  655.  * @brief Base64 encoding algorithm
  656.  * @param[in] input Input data to encode
  657.  * @param[in] inputLen Length of the data to encode
  658.  * @param[out] output NULL-terminated string encoded with Base64 algorithm
  659.  * @param[out] outputLen Length of the encoded string (optional parameter)
  660.  **/
  661. void base64Encode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
  662. {
  663.    size_t n;
  664.    uint8_t a;
  665.    uint8_t b;
  666.    uint8_t c;
  667.    uint8_t d;
  668.    const uint8_t *p;
  669.  
  670.    //Point to the first byte of the input data
  671.    p = (const uint8_t *) input;
  672.  
  673.    //Divide the input stream into blocks of 3 bytes
  674.    n = inputLen / 3;
  675.  
  676.    //A full encoding quantum is always completed at the end of a quantity
  677.    if(inputLen == (n * 3 + 1))
  678.    {
  679.       //The final quantum of encoding input is exactly 8 bits
  680.       if(input != NULL && output != NULL)
  681.       {
  682.          //Read input data
  683.          a = (p[n * 3] & 0xFC) >> 2;
  684.          b = (p[n * 3] & 0x03) << 4;
  685.  
  686.          //The final unit of encoded output will be two characters followed
  687.          //by two "=" padding characters
  688.          output[n * 4] = base64EncTable[a];
  689.          output[n * 4 + 1] = base64EncTable[b];
  690.          output[n * 4 + 2] = '=';
  691.          output[n * 4 + 3] = '=';
  692.          output[n * 4 + 4] = '\0';
  693.       }
  694.  
  695.       //Length of the encoded string (excluding the terminating NULL)
  696.       if(outputLen != NULL)
  697.       {
  698.          *outputLen = n * 4 + 4;
  699.       }
  700.    }
  701.    else if(inputLen == (n * 3 + 2))
  702.    {
  703.       //The final quantum of encoding input is exactly 16 bits
  704.       if(input != NULL && output != NULL)
  705.       {
  706.          //Read input data
  707.          a = (p[n * 3] & 0xFC) >> 2;
  708.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  709.          c = (p[n * 3 + 1] & 0x0F) << 2;
  710.  
  711.          //The final unit of encoded output will be three characters followed
  712.          //by one "=" padding character
  713.          output[n * 4] = base64EncTable[a];
  714.          output[n * 4 + 1] = base64EncTable[b];
  715.          output[n * 4 + 2] = base64EncTable[c];
  716.          output[n * 4 + 3] = '=';
  717.          output[n * 4 + 4] = '\0';
  718.       }
  719.  
  720.       //Length of the encoded string (excluding the terminating NULL)
  721.       if(outputLen != NULL)
  722.       {
  723.          *outputLen = n * 4 + 4;
  724.       }
  725.    }
  726.    else
  727.    {
  728.       //The final quantum of encoding input is an integral multiple of 24 bits
  729.       if(output != NULL)
  730.       {
  731.          //The final unit of encoded output will be an integral multiple of 4
  732.          //characters with no "=" padding
  733.          output[n * 4] = '\0';
  734.       }
  735.  
  736.       //Length of the encoded string (excluding the terminating NULL)
  737.       if(outputLen != NULL)
  738.       {
  739.          *outputLen = n * 4;
  740.       }
  741.    }
  742.  
  743.    //If the output parameter is NULL, then the function calculates the
  744.    //length of the resulting Base64 string without copying any data
  745.    if(input != NULL && output != NULL)
  746.    {
  747.       //The input data is processed block by block
  748.       while(n-- > 0)
  749.       {
  750.          //Read input data
  751.          a = (p[n * 3] & 0xFC) >> 2;
  752.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  753.          c = ((p[n * 3 + 1] & 0x0F) << 2) | ((p[n * 3 + 2] & 0xC0) >> 6);
  754.          d = p[n * 3 + 2] & 0x3F;
  755.  
  756.          //Map each 3-byte block to 4 printable characters using the Base64
  757.          //character set
  758.          output[n * 4] = base64EncTable[a];
  759.          output[n * 4 + 1] = base64EncTable[b];
  760.          output[n * 4 + 2] = base64EncTable[c];
  761.          output[n * 4 + 3] = base64EncTable[d];
  762.       }
  763.    }
  764. }
  765.  
  766. /**
  767.  * @brief Base64 decoding algorithm
  768.  * @param[in] input Base64-encoded string
  769.  * @param[in] inputLen Length of the encoded string
  770.  * @param[out] output Resulting decoded data
  771.  * @param[out] outputLen Length of the decoded data
  772.  * @return Error code
  773.  **/
  774. error_t base64Decode(const char_t *input, size_t inputLen, void *output, size_t *outputLen)
  775. {
  776.    error_t error;
  777.    uint32_t value;
  778.    uint_t c;
  779.    size_t i;
  780.    size_t j;
  781.    size_t n;
  782.    size_t padLen;
  783.    uint8_t *p;
  784.  
  785.    //Check parameters
  786.    if(input == NULL && inputLen != 0)
  787.       return ERROR_INVALID_PARAMETER;
  788.    if(outputLen == NULL)
  789.       return ERROR_INVALID_PARAMETER;
  790.  
  791.    //Initialize status code
  792.    error = NO_ERROR;
  793.  
  794.    //Point to the buffer where to write the decoded data
  795.    p = (uint8_t *) output;
  796.  
  797.    //Initialize variables
  798.    j = 0;
  799.    n = 0;
  800.    value = 0;
  801.    padLen = 0;
  802.  
  803.    //Process the Base64-encoded string
  804.    for(i = 0; i < inputLen && !error; i++)
  805.    {
  806.       //Get current character
  807.       c = (uint_t) input[i];
  808.  
  809.       //Check the value of the current character
  810.       if(c == '\r' || c == '\n')
  811.       {
  812.          //CR and LF characters should be ignored
  813.       }
  814.       else if(c == '=')
  815.       {
  816.          //Increment the number of pad characters
  817.          padLen++;
  818.       }
  819.       else if(c < 128 && base64DecTable[c] < 64 && padLen == 0)
  820.       {
  821.          //Decode the current character
  822.          value = (value << 6) | base64DecTable[c];
  823.  
  824.          //Divide the input stream into blocks of 4 characters
  825.          if(++j == 4)
  826.          {
  827.             //Map each 4-character block to 3 bytes
  828.             if(p != NULL)
  829.             {
  830.                p[n] = (value >> 16) & 0xFF;
  831.                p[n + 1] = (value >> 8) & 0xFF;
  832.                p[n + 2] = value & 0xFF;
  833.             }
  834.  
  835.             //Adjust the length of the decoded data
  836.             n += 3;
  837.  
  838.             //Decode next block
  839.             j = 0;
  840.             value = 0;
  841.          }
  842.       }
  843.       else
  844.       {
  845.          //Implementations must reject the encoded data if it contains
  846.          //characters outside the base alphabet (refer to RFC 4648,
  847.          //section 3.3)
  848.          error = ERROR_INVALID_CHARACTER;
  849.       }
  850.    }
  851.  
  852.    //Check status code
  853.    if(!error)
  854.    {
  855.       //Check the number of pad characters
  856.       if(padLen == 0 && j == 0)
  857.       {
  858.          //No pad characters in this case
  859.       }
  860.       else if(padLen == 1 && j == 3)
  861.       {
  862.          //The "=" sequence indicates that the last block contains only 2 bytes
  863.          if(p != NULL)
  864.          {
  865.             //Decode the last two bytes
  866.             p[n] = (value >> 10) & 0xFF;
  867.             p[n + 1] = (value >> 2) & 0xFF;
  868.          }
  869.  
  870.          //Adjust the length of the decoded data
  871.          n += 2;
  872.       }
  873.       else if(padLen == 2 && j == 2)
  874.       {
  875.          //The "==" sequence indicates that the last block contains only 1 byte
  876.          if(p != NULL)
  877.          {
  878.             //Decode the last byte
  879.             p[n] = (value >> 4) & 0xFF;
  880.          }
  881.  
  882.          //Adjust the length of the decoded data
  883.          n++;
  884.          //Skip trailing pad characters
  885.          i++;
  886.       }
  887.       else
  888.       {
  889.          //The length of the input string must be a multiple of 4
  890.          error = ERROR_INVALID_LENGTH;
  891.       }
  892.    }
  893.  
  894.    //Total number of bytes that have been written
  895.    *outputLen = n;
  896.  
  897.    //Return status code
  898.    return error;
  899. }
  900.  
  901. #endif
  902. //Check crypto library configuration
  903. #if (BASE64URL_SUPPORT == ENABLED)
  904. /**
  905.  * @brief Base64url encoding algorithm
  906.  * @param[in] input Input data to encode
  907.  * @param[in] inputLen Length of the data to encode
  908.  * @param[out] output NULL-terminated string encoded with Base64url algorithm
  909.  * @param[out] outputLen Length of the encoded string (optional parameter)
  910.  **/
  911. void base64urlEncode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
  912. {
  913.    size_t n;
  914.    uint8_t a;
  915.    uint8_t b;
  916.    uint8_t c;
  917.    uint8_t d;
  918.    const uint8_t *p;
  919.  
  920.    //Point to the first byte of the input data
  921.    p = (const uint8_t *) input;
  922.  
  923.    //Divide the input stream into blocks of 3 bytes
  924.    n = inputLen / 3;
  925.  
  926.    //A full encoding quantum is always completed at the end of a quantity
  927.    if(inputLen == (n * 3 + 1))
  928.    {
  929.       //The final quantum of encoding input is exactly 8 bits
  930.       if(input != NULL && output != NULL)
  931.       {
  932.          //Read input data
  933.          a = (p[n * 3] & 0xFC) >> 2;
  934.          b = (p[n * 3] & 0x03) << 4;
  935.  
  936.          //The final unit of encoded output will be two characters
  937.          output[n * 4] = base64urlEncTable[a];
  938.          output[n * 4 + 1] = base64urlEncTable[b];
  939.          output[n * 4 + 2] = '\0';
  940.       }
  941.  
  942.       //Length of the encoded string (excluding the terminating NULL)
  943.       if(outputLen != NULL)
  944.       {
  945.          *outputLen = n * 4 + 2;
  946.       }
  947.    }
  948.    else if(inputLen == (n * 3 + 2))
  949.    {
  950.       //The final quantum of encoding input is exactly 16 bits
  951.       if(input != NULL && output != NULL)
  952.       {
  953.          //Read input data
  954.          a = (p[n * 3] & 0xFC) >> 2;
  955.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  956.          c = (p[n * 3 + 1] & 0x0F) << 2;
  957.  
  958.          //The final unit of encoded output will be three characters followed
  959.          //by one "=" padding character
  960.          output[n * 4] = base64urlEncTable[a];
  961.          output[n * 4 + 1] = base64urlEncTable[b];
  962.          output[n * 4 + 2] = base64urlEncTable[c];
  963.          output[n * 4 + 3] = '\0';
  964.       }
  965.  
  966.       //Length of the encoded string (excluding the terminating NULL)
  967.       if(outputLen != NULL)
  968.       {
  969.          *outputLen = n * 4 + 3;
  970.       }
  971.    }
  972.    else
  973.    {
  974.       //The final quantum of encoding input is an integral multiple of 24 bits
  975.       if(output != NULL)
  976.       {
  977.          //The final unit of encoded output will be an integral multiple of 4
  978.          //characters
  979.          output[n * 4] = '\0';
  980.       }
  981.  
  982.       //Length of the encoded string (excluding the terminating NULL)
  983.       if(outputLen != NULL)
  984.       {
  985.          *outputLen = n * 4;
  986.       }
  987.    }
  988.  
  989.    //If the output parameter is NULL, then the function calculates the
  990.    //length of the resulting Base64url string without copying any data
  991.    if(input != NULL && output != NULL)
  992.    {
  993.       //The input data is processed block by block
  994.       while(n-- > 0)
  995.       {
  996.          //Read input data
  997.          a = (p[n * 3] & 0xFC) >> 2;
  998.          b = ((p[n * 3] & 0x03) << 4) | ((p[n * 3 + 1] & 0xF0) >> 4);
  999.          c = ((p[n * 3 + 1] & 0x0F) << 2) | ((p[n * 3 + 2] & 0xC0) >> 6);
  1000.          d = p[n * 3 + 2] & 0x3F;
  1001.  
  1002.          //Map each 3-byte block to 4 printable characters using the Base64url
  1003.          //character set
  1004.          output[n * 4] = base64urlEncTable[a];
  1005.          output[n * 4 + 1] = base64urlEncTable[b];
  1006.          output[n * 4 + 2] = base64urlEncTable[c];
  1007.          output[n * 4 + 3] = base64urlEncTable[d];
  1008.       }
  1009.    }
  1010. }
  1011.  
  1012. /**
  1013.  * @brief Base64url decoding algorithm
  1014.  * @param[in] input Base64url-encoded string
  1015.  * @param[in] inputLen Length of the encoded string
  1016.  * @param[out] output Resulting decoded data
  1017.  * @param[out] outputLen Length of the decoded data
  1018.  * @return Error code
  1019.  **/
  1020. error_t base64urlDecode(const char_t *input, size_t inputLen, void *output,
  1021.    size_t *outputLen)
  1022. {
  1023.    error_t error;
  1024.    uint32_t value;
  1025.    uint_t c;
  1026.    size_t i;
  1027.    size_t n;
  1028.    uint8_t *p;
  1029.  
  1030.    //Check parameters
  1031.    if(input == NULL && inputLen != 0)
  1032.       return ERROR_INVALID_PARAMETER;
  1033.    if(outputLen == NULL)
  1034.       return ERROR_INVALID_PARAMETER;
  1035.  
  1036.    //Check the length of the input string
  1037.    if((inputLen % 4) == 1)
  1038.       return ERROR_INVALID_LENGTH;
  1039.  
  1040.    //Initialize status code
  1041.    error = NO_ERROR;
  1042.  
  1043.    //Point to the buffer where to write the decoded data
  1044.    p = (uint8_t *) output;
  1045.  
  1046.    //Initialize variables
  1047.    n = 0;
  1048.    value = 0;
  1049.  
  1050.    //Process the Base64url-encoded string
  1051.    for(i = 0; i < inputLen && !error; i++)
  1052.    {
  1053.       //Get current character
  1054.       c = (uint_t) input[i];
  1055.  
  1056.       //Check the value of the current character
  1057.       if(c < 128 && base64urlDecTable[c] < 64)
  1058.       {
  1059.          //Decode the current character
  1060.          value = (value << 6) | base64urlDecTable[c];
  1061.  
  1062.          //Divide the input stream into blocks of 4 characters
  1063.          if((i % 4) == 3)
  1064.          {
  1065.             //Map each 4-character block to 3 bytes
  1066.             if(p != NULL)
  1067.             {
  1068.                p[n] = (value >> 16) & 0xFF;
  1069.                p[n + 1] = (value >> 8) & 0xFF;
  1070.                p[n + 2] = value & 0xFF;
  1071.             }
  1072.  
  1073.             //Adjust the length of the decoded data
  1074.             n += 3;
  1075.             //Decode next block
  1076.             value = 0;
  1077.          }
  1078.       }
  1079.       else
  1080.       {
  1081.          //Implementations must reject the encoded data if it contains
  1082.          //characters outside the base alphabet
  1083.          error = ERROR_INVALID_CHARACTER;
  1084.       }
  1085.    }
  1086.  
  1087.    //Check status code
  1088.    if(!error)
  1089.    {
  1090.       //All trailing pad characters are omitted in Base64url
  1091.       if((inputLen % 4) == 2)
  1092.       {
  1093.          //The last block contains only 1 byte
  1094.          if(p != NULL)
  1095.          {
  1096.             //Decode the last byte
  1097.             p[n] = (value >> 4) & 0xFF;
  1098.          }
  1099.  
  1100.          //Adjust the length of the decoded data
  1101.          n++;
  1102.       }
  1103.       else if((inputLen % 4) == 3)
  1104.       {
  1105.          //The last block contains only 2 bytes
  1106.          if(p != NULL)
  1107.          {
  1108.             //Decode the last two bytes
  1109.             p[n] = (value >> 10) & 0xFF;
  1110.             p[n + 1] = (value >> 2) & 0xFF;
  1111.          }
  1112.  
  1113.          //Adjust the length of the decoded data
  1114.          n += 2;
  1115.       }
  1116.       else
  1117.       {
  1118.          //No pad characters in this case
  1119.       }
  1120.    }
  1121.  
  1122.    //Total number of bytes that have been written
  1123.    *outputLen = n;
  1124.  
  1125.    //Return status code
  1126.    return error;
  1127. }
  1128.  
  1129. #endif
  1130. //Check crypto library configuration
  1131. #if defined(ASN1_SUPPORT)
  1132. /**
  1133.  * @brief Read an ASN.1 tag from the input stream
  1134.  * @param[in] data Input stream where to read the tag
  1135.  * @param[in] length Number of bytes available in the input stream
  1136.  * @param[out] tag Structure describing the ASN.1 tag
  1137.  * @return Error code
  1138.  **/
  1139. error_t asn1ReadTag(const uint8_t *dataV, size_t length, Asn1Tag *tag)
  1140. {
  1141.    uint_t i;
  1142.    uint_t n;
  1143.  
  1144.    //Make sure the identifier octet is present
  1145.    if(length == 0)
  1146.       return ERROR_INVALID_TAG;
  1147.  
  1148.    //Save the class of the ASN.1 tag
  1149.    tag->objClass = dataV[0] & ASN1_CLASS_MASK;
  1150.    //Primitive or constructed encoding?
  1151.    tag->constructed = (dataV[0] & ASN1_ENCODING_CONSTRUCTED) ? TRUE : FALSE;
  1152.  
  1153.    //Check the tag number
  1154.    if((dataV[0u] & ASN1_TAG_NUMBER_MASK) < 31u)
  1155.    {
  1156.       //Tag number is in the range 0 to 30
  1157.       tag->objType = dataV[0] & ASN1_TAG_NUMBER_MASK;
  1158.       //Point to the tag length field
  1159.       i = 1;
  1160.    }
  1161.    else
  1162.    {
  1163.       //If the tag number is greater than or equal to 31,
  1164.       //the subsequent octets will encode the tag number
  1165.       tag->objType = 0;
  1166.  
  1167.       //Decode the tag number
  1168.       for(i = 1; ; i++)
  1169.       {
  1170.          //The field cannot exceed 5 bytes
  1171.          if(i > (sizeof(tag->objType) + 1))
  1172.             return ERROR_INVALID_TAG;
  1173.          //Insufficient number of bytes to decode the tag number?
  1174.          if(!(length - i))
  1175.             return ERROR_INVALID_TAG;
  1176.  
  1177.          //Update the tag number with bits 7 to 1
  1178.          tag->objType = (tag->objType << 7) | (dataV[i] & 0x7F);
  1179.  
  1180.          //Bit 8 shall be set unless it is the last octet
  1181.          if(!(dataV[i] & 0x80))
  1182.             break;
  1183.       }
  1184.       //Point to the tag length field
  1185.       i++;
  1186.    }
  1187.  
  1188.    //Insufficient number of bytes to decode the tag length?
  1189.    if(!(length - i))
  1190.       return ERROR_INVALID_TAG;
  1191.  
  1192.    //Short form is used?
  1193.    if(dataV[i] < 128)
  1194.    {
  1195.       //Bits 7 to 1 encode the number of bytes in the contents
  1196.       tag->length = dataV[i];
  1197.       //Point to the contents of the tag
  1198.       i++;
  1199.    }
  1200.    //Long form is used?
  1201.    else if(dataV[i] > 128 && dataV[i] < 255)
  1202.    {
  1203.       //Bits 7 to 1 encode the number of octets in the length field
  1204.       n = dataV[i] & 0x7F;
  1205.  
  1206.       //The field cannot exceed 4 bytes
  1207.       if(n > sizeof(tag->length))
  1208.          return ERROR_INVALID_TAG;
  1209.       //Insufficient number of bytes to decode the tag length?
  1210.       if((length - i) < n)
  1211.          return ERROR_INVALID_TAG;
  1212.  
  1213.       //Clear the tag length
  1214.       tag->length = 0;
  1215.  
  1216.       //Read the subsequent octets
  1217.       for(i++; n > 0; n--)
  1218.       {
  1219.          tag->length = (tag->length << 8) | dataV[i++];
  1220.       }
  1221.    }
  1222.    //Indefinite form is used?
  1223.    else
  1224.    {
  1225.       //Indefinite form is not supported
  1226.       return ERROR_INVALID_TAG;
  1227.    }
  1228.  
  1229.    //Save the pointer to the tag contents
  1230.    tag->value = dataV + i;
  1231.    //Check the length of tag
  1232.    if((length - i) < tag->length)
  1233.       return ERROR_INVALID_TAG;
  1234.  
  1235.    //Total length occupied by the ASN.1 tag in the input stream
  1236.    tag->totalLength = i + tag->length;
  1237.    //ASN.1 tag successfully decoded
  1238.    return NO_ERROR;
  1239. }
  1240.  
  1241.  
  1242. /**
  1243.  * @brief Read an ASN.1 sequence from the input stream
  1244.  * @param[in] data Input stream where to read the tag
  1245.  * @param[in] length Number of bytes available in the input stream
  1246.  * @param[out] tag Structure describing the ASN.1 tag
  1247.  * @return Error code
  1248.  **/
  1249. error_t asn1ReadSequence(const uint8_t *dataV, size_t length, Asn1Tag *tag)
  1250. {
  1251.    error_t error;
  1252.  
  1253.    //Read ASN.1 tag
  1254.    error = asn1ReadTag(dataV, length, tag);
  1255.  
  1256.    //Check status code
  1257.    if(!error)
  1258.    {
  1259.       //Enforce encoding, class and type
  1260.       error = asn1CheckTag(tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE);
  1261.    }
  1262.  
  1263.    //Return status code
  1264.    return error;
  1265. }
  1266.  
  1267.  
  1268. /**
  1269.  * @brief Read an octet string from the input stream
  1270.  * @param[in] data Input stream where to read the tag
  1271.  * @param[in] length Number of bytes available in the input stream
  1272.  * @param[out] tag Structure describing the ASN.1 tag
  1273.  * @return Error code
  1274.  **/
  1275. error_t asn1ReadOctetString(const uint8_t *dataV, size_t length, Asn1Tag *tag)
  1276. {
  1277.    error_t error;
  1278.  
  1279.    //Read ASN.1 tag
  1280.    error = asn1ReadTag(dataV, length, tag);
  1281.  
  1282.    //Check status code
  1283.    if(!error)
  1284.    {
  1285.       //Enforce encoding, class and type
  1286.       error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING);
  1287.    }
  1288.  
  1289.    //Return status code
  1290.    return error;
  1291. }
  1292.  
  1293.  
  1294. /**
  1295.  * @brief Read an object identifier from the input stream
  1296.  * @param[in] data Input stream where to read the tag
  1297.  * @param[in] length Number of bytes available in the input stream
  1298.  * @param[out] tag Structure describing the ASN.1 tag
  1299.  * @return Error code
  1300.  **/
  1301. error_t asn1ReadOid(const uint8_t *dataV, size_t length, Asn1Tag *tag)
  1302. {
  1303.    error_t error;
  1304.  
  1305.    //Read ASN.1 tag
  1306.    error = asn1ReadTag(dataV, length, tag);
  1307.  
  1308.    //Check status code
  1309.    if(!error)
  1310.    {
  1311.       //Enforce encoding, class and type
  1312.       error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER);
  1313.    }
  1314.  
  1315.    //Return status code
  1316.    return error;
  1317. }
  1318.  
  1319. /**
  1320.  * @brief Read a boolean from the input stream
  1321.  * @param[in] data Input stream where to read the tag
  1322.  * @param[in] length Number of bytes available in the input stream
  1323.  * @param[out] tag Structure describing the ASN.1 tag
  1324.  * @param[out] value Boolean value
  1325.  * @return Error code
  1326.  **/
  1327. error_t asn1ReadBoolean(const uint8_t *dataV, size_t length, Asn1Tag *tag, bool_t *value)
  1328. {
  1329.    error_t error;
  1330.  
  1331.    //Read ASN.1 tag
  1332.    error = asn1ReadTag(dataV, length, tag);
  1333.    //Failed to decode ASN.1 tag?
  1334.    if(error)
  1335.       return error;
  1336.  
  1337.    //Enforce encoding, class and type
  1338.    error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_BOOLEAN);
  1339.    //Invalid tag?
  1340.    if(error)
  1341.       return error;
  1342.  
  1343.    //Make sure the length of the boolean is valid
  1344.    if(tag->length != 1)
  1345.       return ERROR_INVALID_LENGTH;
  1346.  
  1347.    //Read the value of the boolean
  1348.    *value = tag->value[0] ? TRUE : FALSE;
  1349.  
  1350.    //ASN.1 tag successfully decoded
  1351.    return NO_ERROR;
  1352. }
  1353.  
  1354.  
  1355. /**
  1356.  * @brief Read a 32-bit integer from the input stream
  1357.  * @param[in] data Input stream where to read the tag
  1358.  * @param[in] length Number of bytes available in the input stream
  1359.  * @param[out] tag Structure describing the ASN.1 tag
  1360.  * @param[out] value Integer value
  1361.  * @return Error code
  1362.  **/
  1363. error_t asn1ReadInt32(const uint8_t *dataV, size_t length, Asn1Tag *tag, int32_t *value)
  1364. {
  1365.    error_t error;
  1366.    size_t i;
  1367.  
  1368.    //Read ASN.1 tag
  1369.    error = asn1ReadTag(dataV, length, tag);
  1370.    //Failed to decode ASN.1 tag?
  1371.    if(error)
  1372.       return error;
  1373.  
  1374.    //Enforce encoding, class and type
  1375.    error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER);
  1376.    //Invalid tag?
  1377.    if(error)
  1378.       return error;
  1379.  
  1380.    //The contents shall consist of one or more octets
  1381.    if(tag->length < 1 || tag->length > 4)
  1382.       return ERROR_INVALID_TAG;
  1383.  
  1384.    //The contents octets shall be a two's complement binary
  1385.    //number equal to the integer value
  1386.    *value = (tag->value[0] & 0x80) ? -1 : 0;
  1387.  
  1388.    //Process contents octets
  1389.    for(i = 0; i < tag->length; i++)
  1390.    {
  1391.       //Rotate left operation
  1392.       *value <<= 8;
  1393.       //Reconstruct integer value
  1394.       *value |= tag->value[i];
  1395.    }
  1396.  
  1397.    //ASN.1 tag successfully decoded
  1398.    return NO_ERROR;
  1399. }
  1400. /**
  1401.  * @brief Adjust the size of multiple precision integer
  1402.  * @param[in,out] r A multiple precision integer whose size is to be increased
  1403.  * @param[in] size Desired size in words
  1404.  * @return Error code
  1405.  **/
  1406. error_t mpiGrow(Mpi *r, uint8_t size)
  1407. {
  1408.    uint16_t *dataV;
  1409.  
  1410.    size = max(size, 1);                                                         //Ensure the parameter is valid
  1411.  
  1412.    if(r->size >= size)                                                          //Check the current size
  1413.       return NO_ERROR;
  1414.  
  1415.    dataV = (uint16_t*) Malloc(size * MPI_INT_SIZE);                               //Allocate a memory buffer
  1416.    if(dataV == NULL)                                                            //Failed to allocate memory?
  1417.       return ERROR_OUT_OF_MEMORY;
  1418.    memset((void*)dataV,(void*) 0,(int16_t) size * MPI_INT_SIZE);                //Clear buffer contents
  1419.  
  1420.    if(r->size > 0)                                                              //Any data to copy?
  1421.    {
  1422.       memcpy((void*)dataV,(void*) r->dataV,(int16_t) r->size * MPI_INT_SIZE);    //Copy original data
  1423.       //Free(r->data,r->size * MPI_INT_SIZE);                                   Free previously allocated memory
  1424.       Free((char*)dataV,sizeof(dataV));                                                // frees memory block from the Heap allocated by Malloc, pointed to by the dataV pointer
  1425.    }
  1426.    r->size = size;                                                              //Update the size of the multiple precision integer
  1427.    r->dataV = dataV;
  1428.  
  1429.    return NO_ERROR;                                                             //Successful operation
  1430. }
  1431. /**
  1432.  * @brief Octet string to integer conversion
  1433.  *
  1434.  * Converts an octet string to a non-negative integer
  1435.  *
  1436.  * @param[out] r Non-negative integer resulting from the conversion
  1437.  * @param[in] data Octet string to be converted
  1438.  * @param[in] length Length of the octet string
  1439.  * @param[in] format Input format
  1440.  * @return Error code
  1441.  **/
  1442. error_t mpiImport(Mpi *r, const uint8_t *dataV, uint_t length, MpiFormat format)
  1443. {
  1444.    error_t error=0u;
  1445.    uint_t i;
  1446.  
  1447.    //Check input format
  1448.    if(format == MPI_FORMAT_LITTLE_ENDIAN)
  1449.    {
  1450.       //Skip trailing zeroes
  1451.       while(length > 0u && dataV[length - 1] == 0u)
  1452.       {
  1453.          length--;
  1454.       }
  1455.  
  1456.       //Ajust the size of the multiple precision integer
  1457.       error = mpiGrow(r, (length + MPI_INT_SIZE - 1u) / MPI_INT_SIZE);
  1458.      
  1459.       //Check status code
  1460.       if(!error)
  1461.       {
  1462.          //Clear the contents of the multiple precision integer
  1463.          memset(r->dataV, 0u, r->size * MPI_INT_SIZE);
  1464.          //Set sign
  1465.          r->sign = 1u;
  1466.  
  1467.          //Import data
  1468.          for(i = 0u; i < length; i++, dataV++)
  1469.          {
  1470.             r->dataV[i / MPI_INT_SIZE] |= *dataV << ((i % MPI_INT_SIZE) * 8u);
  1471.          }
  1472.       }
  1473.    }
  1474.    else if(format == MPI_FORMAT_BIG_ENDIAN)
  1475.    {
  1476.       //Skip leading zeroes
  1477.       while(length > 1u && *dataV == 0u)
  1478.       {
  1479.          dataV++;
  1480.          length--;
  1481.       }
  1482.  
  1483.       //Ajust the size of the multiple precision integer
  1484.       // ====================== TO PUT IN ====================================== error = mpiGrow(r, (length + MPI_INT_SIZE - 1u) / MPI_INT_SIZE);
  1485.  
  1486.       //Check status code
  1487.       if(!error)
  1488.       {
  1489.          //Clear the contents of the multiple precision integer
  1490.          memset(r->dataV, 0u, r->size * MPI_INT_SIZE);
  1491.          //Set sign
  1492.          r->sign = 1;
  1493.  
  1494.          //Start from the least significant byte
  1495.          dataV += length - 1u;
  1496.  
  1497.          //Import data
  1498.          for(i = 0u; i < length; i++, dataV--)
  1499.          {
  1500.             r->dataV[i / MPI_INT_SIZE] |= *dataV << ((i % MPI_INT_SIZE) * 8u);
  1501.          }
  1502.       }
  1503.    }
  1504.    else
  1505.    {
  1506.       //Report an error
  1507.       error = ERROR_INVALID_PARAMETER;
  1508.    }
  1509.  
  1510.    //Return status code
  1511.    return error;
  1512. }
  1513.  
  1514. /**
  1515.  * @brief Read a multiple-precision integer from the input stream
  1516.  * @param[in] data Input stream where to read the tag
  1517.  * @param[in] length Number of bytes available in the input stream
  1518.  * @param[out] tag Structure describing the ASN.1 tag
  1519.  * @param[out] value Integer value
  1520.  * @return Error code
  1521.  **/
  1522. error_t asn1ReadMpi(const uint8_t *dataV, size_t length, Asn1Tag *tag, Mpi *value)
  1523. {
  1524.    error_t error;
  1525.  
  1526.    //Read ASN.1 tag
  1527.    error = asn1ReadTag(dataV, length, tag);
  1528.    //Failed to decode ASN.1 tag?
  1529.    if(error)
  1530.       return error;
  1531.  
  1532.    //Enforce encoding, class and type
  1533.    error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER);
  1534.    //Invalid tag?
  1535.    if(error)
  1536.       return error;
  1537.  
  1538.    //Negative integer?
  1539.    if(tag->length > 0 && (tag->value[0] & 0x80) != 0)
  1540.       return ERROR_INVALID_SYNTAX;
  1541.  
  1542.    //Convert the octet string to a multiple precision integer
  1543.    error = mpiImport(value, tag->value, tag->length, MPI_FORMAT_BIG_ENDIAN);
  1544.  
  1545.    //Return status code
  1546.    return error;
  1547. }
  1548.  
  1549.  
  1550. /**
  1551.  * @brief Write an ASN.1 tag
  1552.  * @param[in] tag Structure describing the ASN.1 tag
  1553.  * @param[in] reverse Use reverse encoding
  1554.  * @param[out] data Output stream where to write the tag (optional parameter)
  1555.  * @param[out] written Number of bytes written to the output stream (optional parameter)
  1556.  * @return Error code
  1557.  **/
  1558. error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *dataV, size_t *written)
  1559. {
  1560.    size_t i;
  1561.    size_t m;
  1562.    size_t n;
  1563.  
  1564.    //Compute the number of octets that are necessary to encode the tag number
  1565.    if(tag->objType < 31)
  1566.       m = 0;
  1567.    else if(tag->objType < 128)
  1568.       m = 1;
  1569.    else if(tag->objType < 16384)
  1570.       m = 2;
  1571.    else if(tag->objType < 2097152)
  1572.       m = 3;
  1573.    else if(tag->objType < 268435456)
  1574.       m = 4;
  1575.    else
  1576.       m = 5;
  1577.  
  1578.    //Compute the number of octets that are necessary to encode the length field
  1579.    if(tag->length < 128)
  1580.       n = 0;
  1581.    else if(tag->length < 256)
  1582.       n = 1;
  1583.    else if(tag->length < 65536)
  1584.       n = 2;
  1585.    else if(tag->length < 16777216)
  1586.       n = 3;
  1587.    else
  1588.       n = 4;
  1589.  
  1590.    //Valid output stream?
  1591.    if(dataV != NULL)
  1592.    {
  1593.       //Use reverse encoding?
  1594.       if(reverse)
  1595.       {
  1596.          //Any data to copy?
  1597.          if(tag->value != NULL && tag->length > 0)
  1598.          {
  1599.             //Make room for the data
  1600.             dataV -= tag->length;
  1601.             //Copy data
  1602.             memmove((void*)dataV,(void*)tag->value, tag->length);
  1603.          }
  1604.  
  1605.          //Move backward
  1606.          dataV -= m + n + 2;
  1607.       }
  1608.       else
  1609.       {
  1610.          //Any data to copy?
  1611.          if(tag->value != NULL && tag->length > 0)
  1612.          {
  1613.             //Copy data
  1614.             memmove((void*)dataV + m + n + 2u,(void*)tag->value, tag->length);
  1615.          }
  1616.       }
  1617.  
  1618.       //Save the class of the ASN.1 tag
  1619.       dataV[0] = tag->objClass;
  1620.  
  1621.       //Primitive or constructed encoding?
  1622.       if(tag->constructed)
  1623.          dataV[0] |= ASN1_ENCODING_CONSTRUCTED;
  1624.  
  1625.       //Encode the tag number
  1626.       if(m == 0)
  1627.       {
  1628.          //Tag number is in the range 0 to 30
  1629.          dataV[0] |= tag->objType;
  1630.       }
  1631.       else
  1632.       {
  1633.          //The tag number is greater than or equal to 31
  1634.          dataV[0] |= ASN1_TAG_NUMBER_MASK;
  1635.  
  1636.          //The subsequent octets will encode the tag number
  1637.          for(i = 0; i < m; i++)
  1638.          {
  1639.             //Bits 7 to 1 encode the tag number
  1640.             dataV[m - i] = (tag->objType >> (i * 7)) & 0x7F;
  1641.  
  1642.             //Bit 8 of each octet shall be set to one unless it is the
  1643.             //last octet of the identifier octets
  1644.             if(i != 0)
  1645.                dataV[m - i] |= 0x80;
  1646.          }
  1647.       }
  1648.  
  1649.       //Encode the length field
  1650.       if(n == 0)
  1651.       {
  1652.          //Use short form encoding
  1653.          dataV[1 + m] = tag->length & 0x7F;
  1654.       }
  1655.       else
  1656.       {
  1657.          //Bits 7 to 1 encode the number of octets in the length field
  1658.          dataV[1 + m] = 0x80 | (n & 0x7F);
  1659.  
  1660.          //The subsequent octets will encode the length field
  1661.          for(i = 0; i < n; i++)
  1662.          {
  1663.             dataV[1 + m + n - i] = (tag->length >> (i * 8)) & 0xFF;
  1664.          }
  1665.       }
  1666.    }
  1667.  
  1668.    //Total length occupied by the ASN.1 tag
  1669.    tag->totalLength = tag->length + m + n + 2;
  1670.  
  1671.    //The last parameter is optional
  1672.    if(written != NULL)
  1673.    {
  1674.       //Number of bytes written to the output stream
  1675.       *written = m + n + 2;
  1676.  
  1677.       //Any data copied?
  1678.       if(tag->value != NULL)
  1679.          *written += tag->length;
  1680.    }
  1681.  
  1682.    //Successful processing
  1683.    return NO_ERROR;
  1684. }
  1685.  
  1686.  
  1687. /**
  1688.  * @brief Write a 32-bit integer to the output stream
  1689.  * @param[in] value Integer value
  1690.  * @param[in] reverse Use reverse encoding
  1691.  * @param[out] data Output stream where to write the tag (optional parameter)
  1692.  * @param[out] written Number of bytes written to the output stream
  1693.  * @return Error code
  1694.  **/
  1695. error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *dataV, size_t *written)
  1696. {
  1697.    size_t i;
  1698.    size_t n;
  1699.    uint16_t msb;
  1700.  
  1701.    //An integer value is always encoded in the smallest possible number of
  1702.    //octets
  1703.    for(n = 4; n > 1; n--)
  1704.    {
  1705.       //Retrieve the upper 9 bits
  1706.       msb = (value >> (n * 8 - 9)) & 0x01FF;
  1707.  
  1708.       //The upper 9 bits shall not have the same value (all 0 or all 1)
  1709.       if(msb != 0x0000 && msb != 0x01FF)
  1710.          break;
  1711.    }
  1712.  
  1713.    //Valid output stream?
  1714.    if(dataV != NULL)
  1715.    {
  1716.       //Use reverse encoding?
  1717.       if(reverse)
  1718.          dataV -= n + 2;
  1719.  
  1720.       //Write tag type
  1721.       dataV[0] = ASN1_CLASS_UNIVERSAL | ASN1_TYPE_INTEGER;
  1722.       //Write tag length
  1723.       dataV[1] = n & 0xFF;
  1724.  
  1725.       //Write contents octets
  1726.       for(i = 0; i < n; i++)
  1727.       {
  1728.          dataV[1 + n - i] = (value >> (i * 8)) & 0xFF;
  1729.       }
  1730.    }
  1731.  
  1732.    //Number of bytes written to the output stream
  1733.    if(written != NULL)
  1734.       *written = n + 2;
  1735.  
  1736.    //Successful processing
  1737.    return NO_ERROR;
  1738. }
  1739. /**
  1740.  * @brief Get the actual length in bits
  1741.  * @param[in] a Pointer to a multiple precision integer
  1742.  * @return The actual bit count
  1743.  **/
  1744. uint8_t mpiGetBitLength(const Mpi *a)
  1745. {
  1746.    uint8_t n;
  1747.    uint32_t m;
  1748.  
  1749.    //Check whether the specified multiple precision integer is empty
  1750.    if(a->size == 0)
  1751.       return 0;
  1752.  
  1753.    //Start from the most significant word
  1754.    for(n = a->size - 1; n > 0; n--)
  1755.    {
  1756.       //Loop as long as the current word is zero
  1757.       if(a->dataV[n] != 0)
  1758.          break;
  1759.    }
  1760.  
  1761.    //Get the current word
  1762.    m = a->dataV[n];
  1763.    //Convert the length to a bit count
  1764.    n *= MPI_INT_SIZE * 8;
  1765.  
  1766.    //Adjust the bit count
  1767.    for(; m != 0; m >>= 1)
  1768.    {
  1769.       n++;
  1770.    }
  1771.  
  1772.    //Return the actual length in bits
  1773.    return n;
  1774. }
  1775. /**
  1776.  * @brief Get the actual length in bytes
  1777.  * @param[in] a Pointer to a multiple precision integer
  1778.  * @return The actual byte count
  1779.  **/
  1780. uint8_t mpiGetByteLength(const Mpi *a)
  1781. {
  1782.    uint8_t n;
  1783.    uint32_t m;
  1784.  
  1785.    //Check whether the specified multiple precision integer is empty
  1786.    if(a->size == 0)
  1787.       return 0;
  1788.  
  1789.    //Start from the most significant word
  1790.    for(n = a->size - 1; n > 0; n--)
  1791.    {
  1792.       //Loop as long as the current word is zero
  1793.       if(a->dataV[n] != 0)
  1794.          break;
  1795.    }
  1796.  
  1797.    //Get the current word
  1798.    m = a->dataV[n];
  1799.    //Convert the length to a byte count
  1800.    n *= MPI_INT_SIZE;
  1801.  
  1802.    //Adjust the byte count
  1803.    for(; m != 0; m >>= 8)
  1804.    {
  1805.       n++;
  1806.    }
  1807.  
  1808.    //Return the actual length in bytes
  1809.    return n;
  1810. }
  1811. /**
  1812.  * @brief Integer to octet string conversion
  1813.  *
  1814.  * Converts an integer to an octet string of a specified length
  1815.  *
  1816.  * @param[in] a Non-negative integer to be converted
  1817.  * @param[out] data Octet string resulting from the conversion
  1818.  * @param[in] length Intended length of the resulting octet string
  1819.  * @param[in] format Output format
  1820.  * @return Error code
  1821.  **/
  1822. error_t mpiExport(const Mpi *a, uint8_t *dataV, uint8_t length, MpiFormat format)
  1823. {
  1824.    uint8_t i;
  1825.    uint8_t n;
  1826.    error_t error;
  1827.  
  1828.    //Initialize status code
  1829.    error = NO_ERROR;
  1830.  
  1831.    //Check input format
  1832.    if(format == MPI_FORMAT_LITTLE_ENDIAN)
  1833.    {
  1834.       //Get the actual length in bytes
  1835.       n = mpiGetByteLength(a);
  1836.  
  1837.       //Make sure the output buffer is large enough
  1838.       if(n <= length)
  1839.       {
  1840.          //Clear output buffer
  1841.          memset((void*)dataV,(void*) 0,(int16_t) length);
  1842.  
  1843.          //Export data
  1844.          for(i = 0; i < n; i++, dataV++)
  1845.          {
  1846.             *dataV = a->dataV[i / MPI_INT_SIZE] >> ((i % MPI_INT_SIZE) * 8);
  1847.          }
  1848.       }
  1849.       else
  1850.       {
  1851.          //Report an error
  1852.          error = ERROR_INVALID_LENGTH;
  1853.       }
  1854.    }
  1855.    else if(format == MPI_FORMAT_BIG_ENDIAN)
  1856.    {
  1857.       //Get the actual length in bytes
  1858.       n = mpiGetByteLength(a);
  1859.  
  1860.       //Make sure the output buffer is large enough
  1861.       if(n <= length)
  1862.       {
  1863.          //Clear output buffer
  1864.          memset((void*)dataV,(void*) 0,(int16_t) length);
  1865.  
  1866.          //Point to the least significant word
  1867.          dataV += length - 1;
  1868.  
  1869.          //Export data
  1870.          for(i = 0; i < n; i++, dataV--)
  1871.          {
  1872.             *dataV = a->dataV[i / MPI_INT_SIZE] >> ((i % MPI_INT_SIZE) * 8);
  1873.          }
  1874.       }
  1875.       else
  1876.       {
  1877.          //Report an error
  1878.          error = ERROR_INVALID_LENGTH;
  1879.       }
  1880.    }
  1881.    else
  1882.    {
  1883.       //Report an error
  1884.       error = ERROR_INVALID_PARAMETER;
  1885.    }
  1886.  
  1887.    //Return status code
  1888.    return error;
  1889. }
  1890. /**
  1891.  * @brief Write a multiple-precision integer from the output stream
  1892.  * @param[in] value Integer value
  1893.  * @param[in] reverse Use reverse encoding
  1894.  * @param[out] data Output stream where to write the tag (optional parameter)
  1895.  * @param[out] written Number of bytes written to the output stream
  1896.  * @return Error code
  1897.  **/
  1898. error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *dataV, size_t *written)
  1899. {
  1900.    error_t error;
  1901.    size_t n;
  1902.    Asn1Tag tag;
  1903.  
  1904.    //Retrieve the length of the multiple precision integer
  1905.    n = mpiGetBitLength(value);
  1906.  
  1907.    //An integer value is always encoded in the smallest possible number of
  1908.    //octets
  1909.    n = (n / 8) + 1;
  1910.  
  1911.    //Valid output stream?
  1912.    if(dataV != NULL)
  1913.    {
  1914.       //Use reverse encoding?
  1915.       if(reverse)
  1916.          dataV -= n;
  1917.  
  1918.       //The value of the multiple precision integer is encoded MSB first
  1919.       error = mpiExport(value, dataV, n, MPI_FORMAT_BIG_ENDIAN);
  1920.       //Any error to report?
  1921.       if(error)
  1922.          return error;
  1923.    }
  1924.  
  1925.    //The integer is encapsulated within an ASN.1 structure
  1926.    tag.constructed = FALSE;
  1927.    tag.objClass = ASN1_CLASS_UNIVERSAL;
  1928.    tag.objType = ASN1_TYPE_INTEGER;
  1929.    tag.length = n;
  1930.    tag.value = dataV;
  1931.  
  1932.    //Compute the length of the corresponding ASN.1 structure
  1933.    error = asn1WriteTag(&tag, FALSE, dataV, NULL);
  1934.    //Any error to report?
  1935.    if(error)
  1936.       return error;
  1937.  
  1938.    //Number of bytes written to the output stream
  1939.    if(written != NULL)
  1940.       *written = tag.totalLength;
  1941.  
  1942.    //Successful processing
  1943.    return NO_ERROR;
  1944. }
  1945.  
  1946. /**
  1947.  * @brief Enforce the type of a specified tag
  1948.  * @param[in] tag Pointer to an ASN.1 tag
  1949.  * @param[in] constructed Expected encoding (TRUE for constructed, FALSE
  1950.  *   for primitive)
  1951.  * @param[in] objClass Expected tag class
  1952.  * @param[in] objType Expected tag type
  1953.  * @return Error code
  1954.  **/
  1955. error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
  1956. {
  1957.    //Check encoding
  1958.    if(tag->constructed != constructed)
  1959.       return ERROR_WRONG_ENCODING;
  1960.    //Enforce class
  1961.    if(tag->objClass != objClass)
  1962.       return ERROR_INVALID_CLASS;
  1963.    //Enforce type
  1964.    if(tag->objType != objType)
  1965.       return ERROR_INVALID_TYPE;
  1966.  
  1967.    //The tag matches all the criteria
  1968.    return NO_ERROR;
  1969. }
  1970. /**
  1971.  * @brief Compare object identifiers
  1972.  * @param[in] oid1 Pointer the first OID
  1973.  * @param[in] oidLen1 Length of the first OID, in bytes
  1974.  * @param[in] oid2 Pointer the second OID
  1975.  * @param[in] oidLen2 Length of the second OID, in bytes
  1976.  * @return Comparison result
  1977.  * @retval 0 Objects identifiers are equal
  1978.  * @retval -1 The first OID lexicographically precedes the second OID
  1979.  * @retval 1 The second OID lexicographically precedes the first OID
  1980.  **/
  1981. int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
  1982. {
  1983.    size_t i;
  1984.  
  1985.    //Perform lexicographical comparison
  1986.    for(i = 0; i < oidLen1 && i < oidLen2; i++)
  1987.    {
  1988.       //Compare current byte
  1989.       if(oid1[i] < oid2[i])
  1990.          return -1;
  1991.       else if(oid1[i] > oid2[i])
  1992.          return 1;
  1993.    }
  1994.  
  1995.    //Compare length
  1996.    if(oidLen1 < oidLen2)
  1997.       return -1;
  1998.    else if(oidLen1 > oidLen2)
  1999.       return 1;
  2000.  
  2001.    //Object identifiers are equal
  2002.    return 0;
  2003. }
  2004.  
  2005. /**
  2006.  * @brief Check ASN.1 tag against a specified OID
  2007.  * @param[in] tag Pointer to an ASN.1 tag
  2008.  * @param[in] oid Expected object identifier (OID)
  2009.  * @param[in] length Length of the OID
  2010.  * @return Error code
  2011.  **/
  2012. error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
  2013. {
  2014.    error_t error;
  2015.  
  2016.    //Enforce encoding, class and type
  2017.    error = asn1CheckTag(tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OBJECT_IDENTIFIER);
  2018.    //Any error to report?
  2019.    if(error)
  2020.       return error;
  2021.  
  2022.    //Compare OID against the specified value
  2023.    if(oidComp(tag->value, tag->length, oid, length))
  2024.      return ERROR_WRONG_IDENTIFIER;
  2025.  
  2026.    //The tag matches all the criteria
  2027.    return NO_ERROR;
  2028. }
  2029.  
  2030.  
  2031. /**
  2032.  * @brief Display an ASN.1 data object
  2033.  * @param[in] data Pointer to the ASN.1 object to dump
  2034.  * @param[in] length Length of the ASN.1 object
  2035.  * @param[in] level Current level of recursion (this parameter shall be set to 0)
  2036.  * @return Error code
  2037.  **/
  2038.  
  2039. error_t asn1DumpObject(const uint8_t *dataV, size_t length, uint_t level)
  2040. {
  2041. //Check debugging level
  2042. #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
  2043.    error_t error;
  2044.    uint_t i;
  2045.    Asn1Tag tag;
  2046.  
  2047.    //ASN.1 universal types
  2048.    static const char_t *label[32] =
  2049.    {
  2050.       "[0]",
  2051.       "BOOLEAN",
  2052.       "INTEGER",
  2053.       "BIT STRING",
  2054.       "OCTET STRING",
  2055.       "NULL",
  2056.       "OBJECT IDENTIFIER",
  2057.       "OBJECT DESCRIPTOR",
  2058.       "EXTERNAL",
  2059.       "REAL",
  2060.       "ENUMERATED",
  2061.       "[11]",
  2062.       "UTF8 STRING",
  2063.       "[13]",
  2064.       "[14]",
  2065.       "[15]",
  2066.       "SEQUENCE",
  2067.       "SET",
  2068.       "NUMERIC STRING",
  2069.       "PRINTABLE STRING",
  2070.       "TELETEX STRING",
  2071.       "VIDEOTEX STRING",
  2072.       "IA5 STRING",
  2073.       "UTC TIME",
  2074.       "GENERALIZED TIME",
  2075.       "GRAPHIC STRING",
  2076.       "VISIBLE STRING",
  2077.       "GENERAL STRING",
  2078.       "UNIVERSAL STRING",
  2079.       "[29]",
  2080.       "BMP STRING",
  2081.       "[31]"
  2082.    };
  2083.  
  2084.    //Prefix used to format the structure
  2085.    static const char_t *prefix[10] =
  2086.    {
  2087.       "",
  2088.       "  ",
  2089.       "    ",
  2090.       "      ",
  2091.       "        ",
  2092.       "          ",
  2093.       "            ",
  2094.       "              ",
  2095.       "                ",
  2096.       "                  "
  2097.    };
  2098.  
  2099.    //Parse ASN.1 object
  2100.    while(length > 0)
  2101.    {
  2102.       //Decode current ASN.1 tag
  2103.       error = asn1ReadTag(dataV, length, &tag);
  2104.       //Decoding failed?
  2105.       if(error)
  2106.          return error;
  2107.  
  2108.       //Point to the next field
  2109.       dataV += tag.totalLength;
  2110.       length -= tag.totalLength;
  2111.  
  2112.       //Dump tag number, tag class, and contents length fields
  2113.       if(tag.objType < 32 && (tag.objClass & ASN1_CLASS_MASK) == ASN1_CLASS_UNIVERSAL)
  2114.          TRACE_DEBUG("%s%s (%" PRIuSIZE " bytes)\r\n", prefix[level], label[tag.objType], tag.length);
  2115.       else
  2116.          TRACE_DEBUG("%s[%u] (%" PRIuSIZE " bytes)\r\n", prefix[level], tag.objType, tag.length);
  2117.  
  2118.       //Constructed type?
  2119.       if(tag.constructed)
  2120.       {
  2121.          //Check whether the maximum level of recursion is reached
  2122.          if(level < 8)
  2123.          {
  2124.             //Recursive decoding of the ASN.1 tag
  2125.             error = asn1DumpObject(tag.value, tag.length, level + 1);
  2126.             //Decoding failed?
  2127.             if(error)
  2128.                return error;
  2129.          }
  2130.          else
  2131.          {
  2132.             //If the maximum level of recursion is reached, then dump contents
  2133.             TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
  2134.          }
  2135.       }
  2136.       //Primitive type?
  2137.       else
  2138.       {
  2139.          //Check the type of the current tag
  2140.          switch(tag.objType)
  2141.          {
  2142.          //OID?
  2143.          case ASN1_TYPE_OBJECT_IDENTIFIER:
  2144.             //Append prefix
  2145.             TRACE_DEBUG(prefix[level + 1]);
  2146.             //Print OID
  2147.             TRACE_DEBUG("%s", oidToString(tag.value, tag.length, NULL, 0));
  2148.             //Add a line feed
  2149.             TRACE_DEBUG("\r\n");
  2150.             break;
  2151.  
  2152.          //String?
  2153.          case ASN1_TYPE_UTF8_STRING:
  2154.          case ASN1_TYPE_NUMERIC_STRING:
  2155.          case ASN1_TYPE_PRINTABLE_STRING:
  2156.          case ASN1_TYPE_TELETEX_STRING:
  2157.          case ASN1_TYPE_VIDEOTEX_STRING:
  2158.          case ASN1_TYPE_IA5_STRING:
  2159.          case ASN1_TYPE_GRAPHIC_STRING:
  2160.          case ASN1_TYPE_VISIBLE_STRING:
  2161.          case ASN1_TYPE_GENERAL_STRING:
  2162.          case ASN1_TYPE_UNIVERSAL_STRING:
  2163.          case ASN1_TYPE_BMP_STRING:
  2164.             //Append prefix
  2165.             TRACE_DEBUG("%s", prefix[level + 1]);
  2166.  
  2167.             //Dump the entire string
  2168.             for(i = 0; i < tag.length; i++)
  2169.             {
  2170.                TRACE_DEBUG("%c", tag.value[i]);
  2171.             }
  2172.  
  2173.             //Add a line feed
  2174.             TRACE_DEBUG("\r\n");
  2175.             break;
  2176.  
  2177.          //UTC time?
  2178.          case ASN1_TYPE_UTC_TIME:
  2179.             //Check length
  2180.             if(tag.length != 13)
  2181.                return ERROR_WRONG_ENCODING;
  2182.             //The encoding shall terminate with a "Z"
  2183.             if(tag.value[tag.length - 1] != 'Z')
  2184.                return ERROR_WRONG_ENCODING;
  2185.  
  2186.             //Append prefix
  2187.             TRACE_DEBUG("%s", prefix[level + 1]);
  2188.             //Display date
  2189.             TRACE_DEBUG("%c%c/%c%c/%c%c ", tag.value[0], tag.value[1],
  2190.                tag.value[2], tag.value[3], tag.value[4], tag.value[5]);
  2191.             //Display time
  2192.             TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[6], tag.value[7],
  2193.                tag.value[8], tag.value[9], tag.value[10], tag.value[11]);
  2194.             //Add a line feed
  2195.             TRACE_DEBUG("\r\n");
  2196.             break;
  2197.  
  2198.          //Generalized time?
  2199.          case ASN1_TYPE_GENERALIZED_TIME:
  2200.             //Check length
  2201.             if(tag.length != 15)
  2202.                return ERROR_WRONG_ENCODING;
  2203.             //The encoding shall terminate with a "Z"
  2204.             if(tag.value[tag.length - 1] != 'Z')
  2205.                return ERROR_WRONG_ENCODING;
  2206.  
  2207.             //Append prefix
  2208.             TRACE_DEBUG("%s", prefix[level + 1]);
  2209.             //Display date
  2210.             TRACE_DEBUG("%c%c%c%c/%c%c/%c%c ", tag.value[0], tag.value[1], tag.value[2],
  2211.                tag.value[3], tag.value[4], tag.value[5], tag.value[6], tag.value[7]);
  2212.             //Display time
  2213.             TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[8], tag.value[9],
  2214.                tag.value[10], tag.value[11], tag.value[12], tag.value[13]);
  2215.             //Add a line feed
  2216.             TRACE_DEBUG("\r\n");
  2217.             break;
  2218.  
  2219.          //Any other type?
  2220.          default:
  2221.             //Dump the contents of the tag
  2222.             TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
  2223.             break;
  2224.          }
  2225.       }
  2226.    }
  2227. #endif
  2228.  
  2229.    //ASN.1 object successfully decoded
  2230.    return NO_ERROR;
  2231. }
  2232.  
  2233. //
  2234. // Args:- CodBinLeitura (input char stream)
  2235. //        CartaoWiegand (output char stream)
  2236. // Example :-
  2237. //            Lcd_Cmd(_LCD_CLEAR) ;
  2238. //            Lcd_Out(1, 1, "Codigo Cartao:" ) ;
  2239. //            Lcd_Out(2, 1, CartaoWiegand) ;
  2240. //
  2241. // CodBinLeitura is created like this from on to off state transitions :-
  2242. //
  2243. //          if (PORTB.RB6 == 0 && disparo == 0){
  2244. //             CodBinLeitura[cont] = '0';
  2245. //             cont++;
  2246. //             delay_ms(1);
  2247. //             disparo = 1;
  2248. //          }
  2249. //          if (PORTB.RB7 == 0 && disparo == 0){
  2250. //             CodBinLeitura [cont] = '1';
  2251. //             cont ++;
  2252. //             delay_ms(1);
  2253. //             disparo = 1;
  2254. //          }
  2255. //          if (PORTB.RB6 == 1 && PORTB.RB7 == 1){
  2256. //             disparo = 0;
  2257. //          }
  2258. //
  2259. //  RB6 and RB7 are inputs onto the PIC MCU  where display is attached
  2260. //
  2261. void ConvertWiegand(char* CodBinLeitura, char* CartaoWiegand )
  2262. {
  2263.       int32_t FacilityDecimal = 0,
  2264.               CartaoDecimal = 0;
  2265.       int16_t  i;
  2266.       int8_t valLen;
  2267.       char WiegandFacility[8u],
  2268.            WiegandCartao[16u],
  2269.            AuxFacility[12u],
  2270.            AuxCartao[12u];
  2271.  
  2272.       if (strlen(CodBinLeitura)<=23)                                            // input not long enough
  2273.       {
  2274.          return;
  2275.       }
  2276.      
  2277.       for (i=0;i<8;i++){
  2278.           WiegandFacility[i] = CodBinLeitura[i+1];                              // first 8 bits from CodBinLeitura input to function are copied to Wiegand Facility
  2279.       }
  2280.       for (i=0;i<16;i++){
  2281.           WiegandCartao[i] =  CodBinLeitura[i+9];                               // next 16 bits from CodBinLeitura input to function are copied to Wiegand Cartao
  2282.       }
  2283.       for (i=0;i<8;i++){                                                        // convert the 8 bit bináry input into decimal and write the number to facility decimal
  2284.           if (WiegandFacility[i] == '1')
  2285.           {
  2286.              FacilityDecimal = FacilityDecimal + ldexp (1,7-i);                 // pow(2.,15.-j);
  2287.           }
  2288.       }
  2289.       for (i=0;i<16;i++){                                                       // convert the 16 bit bináry input into decimal and write the number to cartao decimal
  2290.           if (WiegandCartao[i] == '1')
  2291.           {
  2292.              CartaoDecimal = CartaoDecimal + ldexp (1,15-i);                    // pow(2.,15.-j);
  2293.           }
  2294.       }
  2295.       // LongIntToStrWithZeros(FacilityDecimal, AuxFacility);
  2296.       if (FacilityDecimal>=100)                                                 // string to be made 11 long e.g. 00000000255
  2297.       {
  2298.          valLen = 3;                                                            // 3 chars long
  2299.       }
  2300.       else if ((FacilityDecimal<100) && (FacilityDecimal>=10))                  // between 100 and 10
  2301.       {
  2302.          valLen = 2;                                                            // 2 chars long
  2303.       }
  2304.       else if ((FacilityDecimal<10) && (FacilityDecimal>=1))                    // between 10 and 1
  2305.       {
  2306.          valLen = 1;                                                            // 1 char long
  2307.       }
  2308.       else
  2309.       {
  2310.          valLen = 0;                                                            // no number
  2311.       }
  2312.       for (i=0;i<12-valLen;i++) {
  2313.          AuxFacility[i] = '0';                                                  // pad the zeros
  2314.       }
  2315.       AuxFacility[i] = '\0';                                                    // terminate the string
  2316.       sprintf(AuxFacility,"%s%d",AuxFacility,FacilityDecimal);                  // add the number
  2317.  
  2318.                                                                                
  2319.       // LongIntToStrWithZeros(CartaoDecimal, AuxCartao);
  2320.       if (CartaoDecimal>=10000)                                                 // string to be made 11 long e.g. 00000065535
  2321.       {
  2322.          valLen = 5;                                                            // 5 chars long
  2323.       }
  2324.       else if ((CartaoDecimal<10000) && (CartaoDecimal>=1000))                  // between 1000 and 10000
  2325.       {
  2326.          valLen = 4;                                                            // 4 chars long
  2327.       }
  2328.       else if ((CartaoDecimal>=100) && (CartaoDecimal<1000))                    // between 100 and 1000
  2329.       {
  2330.          valLen = 3;                                                            // 3 chars long
  2331.       }
  2332.       else if ((CartaoDecimal<100) && (CartaoDecimal>=10))                      // between 10 and 100
  2333.       {
  2334.          valLen = 2;                                                            // two chars long
  2335.       }
  2336.       else if ((CartaoDecimal<10) && (CartaoDecimal>=1))                        // between 1 and 10
  2337.       {
  2338.          valLen = 1;                                                            // 1 char long
  2339.       }
  2340.       else                                                                      // zero
  2341.       {
  2342.          valLen = 0;                                                            // no number
  2343.       }
  2344.       for (i=0;i<12-valLen;i++) {
  2345.          AuxCartao[i] = '0';                                                    // pad the zeros
  2346.       }
  2347.       sprintf(AuxCartao,"%s%d",AuxCartao,CartaoDecimal);                        // tab the decimal number to the 00 paded string
  2348.  
  2349.                                                                                
  2350.       for (i=0;i<6;i++){
  2351.           CartaoWiegand[i] = '0';                                               // pad 6 zeros on Cartao Wiegand
  2352.       }
  2353.       for (i=0;i<3;i++){                                                        // now tag auxfacility to the cartao wiegand string
  2354.           CartaoWiegand[i+6] = AuxFacility[i+8];                                // now copy the last 3 chars offset by 8 in AuxFacility into Cartao Wiegand offset by 6
  2355.       }
  2356.       for (i=0;i<6;i++){                                                        // now tag auxcartao to the cartao wiegand string
  2357.           CartaoWiegand[i+9] = AuxCartao[i+6];                                  // now copy the last 6 chars offset by 6 in AuxCatao into Cartao Wiegand offset by 9
  2358.       }                                                                         // Cartao wiegand is complete
  2359. }
  2360.  
  2361. /**
  2362.  * ZigZag encoding maps all values of a signed integer into those of an unsigned integer in such
  2363.  * a way that numbers of small absolute value correspond to small integers in the result.
  2364.  *
  2365.  * (Compared to just casting a signed to an unsigned which creates huge resulting numbers for
  2366.  * small negative integers).
  2367.  */
  2368. uint32_t zigzagEncode(int32_t value)
  2369. {
  2370.     return (uint32_t)((value << 1u) ^ (value >> 31u));
  2371. }
  2372. /*-----------------------------------------------------------------------------
  2373.  *   huffmanEncodeBuf():  huffman encoding of buffer
  2374.  *
  2375.  *  Parameters: uint8_t *outBuf, int16_t outBufLen, const uint8_t *inBuf,  
  2376.  *              int16_t inLen, const huffmanTable_t *huffmanTable
  2377.  *
  2378.  *  Return:     int16_t  _ERR_PARSE_ERROR_ or _ERR_OK_
  2379.  *            
  2380.  *----------------------------------------------------------------------------*/
  2381. int16_t huffmanEncodeBuf(uint8_t *outBuf, int16_t outBufLen, const uint8_t *inBuf, int16_t inLen, const huffmanTable_t *huffmanTable)
  2382. {
  2383.     int16_t ret = 0;
  2384.     int16_t huffCodeLen;
  2385.     uint16_t huffCode;
  2386.     uint16_t testBit;
  2387.     int16_t ii;
  2388.     int16_t jj;
  2389.     uint8_t outBit = 0x80u;
  2390.     uint8_t *outByte = NULL;
  2391.  
  2392.     if (((outBuf == NULL) || (inBuf == NULL)) || (huffmanTable == NULL))
  2393.     { /* for misra */ }
  2394.     else
  2395.     {
  2396.        outByte = outBuf;
  2397.    
  2398.        for (ii = 0; ii < inLen; ++ii)
  2399.        {
  2400.            huffCodeLen = huffmanTable[*inBuf]->codeLen;
  2401.            huffCode = huffmanTable[*inBuf]->hCode;
  2402.            ++inBuf;
  2403.            testBit = 0x8000u;
  2404.            for (jj = 0; jj < huffCodeLen; ++jj)
  2405.            {
  2406.                if (huffCode & testBit)
  2407.                {
  2408.                    *outByte |= outBit;
  2409.                }
  2410.                testBit >>= 1;
  2411.                outBit >>= 1;
  2412.                if (outBit == 0)
  2413.                {
  2414.                    outBit = 0x80u;
  2415.                    ++outByte;
  2416.                    *outByte = 0;
  2417.                    ret=++ret % INT16_MAX;
  2418.                }
  2419.                if (ret >= outBufLen && ii < inLen - 1 && jj < huffCodeLen - 1)
  2420.                {
  2421.                    ret=-1;
  2422.                }
  2423.            }
  2424.         }
  2425.         if ((outBit != 0x80)&&(ret != -1))
  2426.         {
  2427.            ret=++ret % INT16_MAX;                                               // ensure last character in output buffer is counted
  2428.         }
  2429.     }
  2430.     return ret;
  2431. }
  2432. /*-----------------------------------------------------------------------------
  2433.  *   huffmanEncodeBufStreaming():  huffman encoding
  2434.  *
  2435.  *  Parameters: huffmanState_t *state, const uint8_t *inBuf, int16_t inLen,
  2436.  *              const huffmanTable_t *huffmanTable
  2437.  *
  2438.  *  Return:     int16_t  _ERR_PARSE_ERROR_ or _ERR_OK_
  2439.  *            
  2440.  *----------------------------------------------------------------------------*/
  2441. int16_t huffmanEncodeBufStreaming(huffmanState_t *state, const uint8_t *inBuf, int16_t inLen, const huffmanTable_t *huffmanTable)
  2442. {
  2443.     uint8_t *savedOutBytePtr = state->outByte;
  2444.     uint8_t savedOutByte = *savedOutBytePtr;
  2445.     uint8_t *pos = NULL;
  2446.     int16_t huffCodeLen;
  2447.     uint16_t huffCode;
  2448.     uint16_t testBit;
  2449.     int16_t jj;
  2450.     int16_t ret=0;
  2451.     uint8_t end = 0u;
  2452.  
  2453.     if (((state == NULL) || (inBuf == NULL)) || (huffmanTable == NULL))         /* guard null pointer */
  2454.     { /* for misra */ }
  2455.     else
  2456.     {
  2457.        for (pos = (uint8_t *)inBuf, end = (uint8_t )inBuf + (uint8_t )inLen; (uint8_t)pos < end; ++pos)                 /* for the encoder byte stream */
  2458.        {
  2459.            huffCodeLen = huffmanTable[*pos]->codeLen;                           /* look up the length from the huffman table for that char */
  2460.            huffCode = huffmanTable[*pos]->hCode;                                /* look up the code for that char read from the stream */
  2461.            testBit = 0x8000u;
  2462.            for (jj = 0; jj < huffCodeLen; ++jj)
  2463.            {
  2464.               if (huffCode & testBit)                                           /* MSB is set */
  2465.               {
  2466.                  *state->outByte |= state->outBit;                              /* or with the outBit */
  2467.               }
  2468.               testBit >>= 1;                                                    /* shift to the left */
  2469.               state->outBit >>= 1;
  2470.               if (state->outBit == 0)                                           /* gone to zero */
  2471.               {
  2472.                  state->outBit = 0x80;                                          /* reset to 80 */
  2473.                  ++state->outByte;
  2474.                  *state->outByte = 0;
  2475.                  ++state->bytesWritten;
  2476.               }
  2477.               if (state->bytesWritten >= state->outBufLen && ((uint8_t)pos < end - 1 || jj < huffCodeLen - 1)) // if buffer is filled and we haven't finished compressing
  2478.               {
  2479.                  *savedOutBytePtr = savedOutByte;                               // restore savedOutByte
  2480.                  ret=-1;
  2481.               }
  2482.            }
  2483.         }
  2484.     }
  2485.     return ret;
  2486. }
  2487. #endif
  2488.  
  2489. /*
  2490.    Ported from
  2491.    https://github.com/Bownairo/ctrulib/blob/master/libctru/source/util/utf/decode_utf8.c
  2492. */
  2493.  
  2494. /*-----------------------------------------------------------------------------
  2495.  *  encode_utf16:  utf16 encode
  2496.  *
  2497.  *  Parameters: uint16_t *out, uint32_t in
  2498.  *
  2499.  *  Return: int16_t
  2500.  *            
  2501.  *----------------------------------------------------------------------------*/
  2502. int16_t encode_utf16(uint16_t *out, uint32_t in)
  2503. {
  2504.   if(in < 0x10000)
  2505.   {
  2506.     if(out != NULL)
  2507.       *out++ = in;
  2508.     return 1;
  2509.   }
  2510.   else if(in < 0x110000)
  2511.   {
  2512.     if(out != NULL)
  2513.     {
  2514.       *out++ = (in >> 10) + 0xD7C0;
  2515.       *out++ = (in & 0x3FF) + 0xDC00;
  2516.     }
  2517.     return 2;
  2518.   }
  2519.  
  2520.   return -1;
  2521. }
  2522.  
  2523. /*-----------------------------------------------------------------------------
  2524.  *  decode_utf16:  utf16 decode
  2525.  *
  2526.  *  Parameters: uint32_t *out, const uint16_t *in
  2527.  *
  2528.  *  Return: int16_t
  2529.  *            
  2530.  *----------------------------------------------------------------------------*/
  2531. int16_t decode_utf16(uint32_t *out, const uint16_t *in)
  2532. {
  2533.   uint16_t code1, code2;
  2534.  
  2535.   code1 = *in++;
  2536.   if(code1 >= 0xD800 && code1 < 0xDC00)
  2537.   {
  2538.     /* surrogate pair */
  2539.     code2 = *in++;
  2540.     if(code2 >= 0xDC00 && code2 < 0xE000)
  2541.     {
  2542.       *out = (code1 << 10) + code2 - 0x35FDC00;
  2543.       return 2;
  2544.     }
  2545.  
  2546.     return -1;
  2547.   }
  2548.  
  2549.   *out = code1;
  2550.   return 1;
  2551. }
  2552.  
  2553. /*-----------------------------------------------------------------------------
  2554.  *  decode_utf8:  utf8 decode
  2555.  *
  2556.  *  Parameters: uint32_t *out, const uint8_t *in
  2557.  *
  2558.  *  Return: int16_t
  2559.  *            
  2560.  *----------------------------------------------------------------------------*/
  2561. int16_t decode_utf8(uint32_t *out, const uint8_t *in)
  2562. {
  2563.   uint8_t code1, code2, code3, code4;
  2564.  
  2565.   code1 = *in++;
  2566.   if(code1 < 0x80)
  2567.   {
  2568.     /* 1-byte sequence */
  2569.     *out = code1;
  2570.     return 1;
  2571.   }
  2572.   else if(code1 < 0xC2)
  2573.   {
  2574.     return -1;
  2575.   }
  2576.   else if(code1 < 0xE0)
  2577.   {
  2578.     /* 2-byte sequence */
  2579.     code2 = *in++;
  2580.     if((code2 & 0xC0) != 0x80)
  2581.     {
  2582.       return -1;
  2583.     }
  2584.  
  2585.     *out = (code1 << 6) + code2 - 0x3080;
  2586.     return 2;
  2587.   }
  2588.   else if(code1 < 0xF0)
  2589.   {
  2590.     /* 3-byte sequence */
  2591.     code2 = *in++;
  2592.     if((code2 & 0xC0) != 0x80)
  2593.     {
  2594.       return -1;
  2595.     }
  2596.     if(code1 == 0xE0 && code2 < 0xA0)
  2597.     {
  2598.       return -1;
  2599.     }
  2600.  
  2601.     code3 = *in++;
  2602.     if((code3 & 0xC0) != 0x80)
  2603.     {
  2604.       return -1;
  2605.     }
  2606.  
  2607.     *out = (code1 << 12) + (code2 << 6) + code3 - 0xE2080;
  2608.     return 3;
  2609.   }
  2610.   else if(code1 < 0xF5)
  2611.   {
  2612.     /* 4-byte sequence */
  2613.     code2 = *in++;
  2614.     if((code2 & 0xC0) != 0x80)
  2615.     {
  2616.       return -1;
  2617.     }
  2618.     if(code1 == 0xF0 && code2 < 0x90)
  2619.     {
  2620.       return -1;
  2621.     }
  2622.     if(code1 == 0xF4 && code2 >= 0x90)
  2623.     {
  2624.       return -1;
  2625.     }
  2626.  
  2627.     code3 = *in++;
  2628.     if((code3 & 0xC0) != 0x80)
  2629.     {
  2630.       return -1;
  2631.     }
  2632.  
  2633.     code4 = *in++;
  2634.     if((code4 & 0xC0) != 0x80)
  2635.     {
  2636.       return -1;
  2637.     }
  2638.  
  2639.     *out = (code1 << 18) + (code2 << 12) + (code3 << 6) + code4 - 0x3C82080;
  2640.     return 4;
  2641.   }
  2642.  
  2643.   return -1;
  2644. }
  2645. /*
  2646.  * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
  2647.  */
  2648. /*-----------------------------------------------------------------------------
  2649.  *  utf8_encode():  utf8 encoding
  2650.  *
  2651.  *  Parameters: int32_t codepoint, char *buffer, size_t *size
  2652.  *
  2653.  *  Return:     int16_t  -1 (error) or 0
  2654.  *            
  2655.  *----------------------------------------------------------------------------*/
  2656. int16_t utf8_encode(int32_t codepoint, char *buffer, size_t *size)
  2657. {
  2658.     if (codepoint < 0)
  2659.         return -1;
  2660.     else if (codepoint < 0x80) {
  2661.         buffer[0] = (char)codepoint;
  2662.         *size = 1;
  2663.     } else if (codepoint < 0x800) {
  2664.         buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6);
  2665.         buffer[1] = 0x80 + ((codepoint & 0x03F));
  2666.         *size = 2;
  2667.     } else if (codepoint < 0x10000) {
  2668.         buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12);
  2669.         buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6);
  2670.         buffer[2] = 0x80 + ((codepoint & 0x003F));
  2671.         *size = 3;
  2672.     } else if (codepoint <= 0x10FFFF) {
  2673.         buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18);
  2674.         buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12);
  2675.         buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6);
  2676.         buffer[3] = 0x80 + ((codepoint & 0x00003F));
  2677.         *size = 4;
  2678.     } else
  2679.         return -1;
  2680.  
  2681.     return 0;
  2682. }
  2683. /*-----------------------------------------------------------------------------
  2684.  *  utf8_check_first():  utf8 encoding
  2685.  *
  2686.  *  Parameters: char byte
  2687.  *
  2688.  *  Return: size_t
  2689.  *            
  2690.  *----------------------------------------------------------------------------*/
  2691. size_t utf8_check_first(char byte)
  2692. {
  2693.     unsigned char u = (unsigned char)byte;
  2694.  
  2695.     if (u < 0x80)
  2696.         return 1;
  2697.  
  2698.     if (0x80 <= u && u <= 0xBF) {
  2699.         /* second, third or fourth byte of a multi-byte
  2700.            sequence, i.e. a "continuation byte" */
  2701.         return 0;
  2702.     } else if (u == 0xC0 || u == 0xC1) {
  2703.         /* overlong encoding of an ASCII byte */
  2704.         return 0;
  2705.     } else if (0xC2 <= u && u <= 0xDF) {
  2706.         /* 2-byte sequence */
  2707.         return 2;
  2708.     }
  2709.  
  2710.     else if (0xE0 <= u && u <= 0xEF) {
  2711.         /* 3-byte sequence */
  2712.         return 3;
  2713.     } else if (0xF0 <= u && u <= 0xF4) {
  2714.         /* 4-byte sequence */
  2715.         return 4;
  2716.     } else { /* u >= 0xF5 */
  2717.         /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
  2718.            UTF-8 */
  2719.         return 0;
  2720.     }
  2721. }
  2722. /*-----------------------------------------------------------------------------
  2723.  *  utf8_check_full():  utf8 encoding
  2724.  *
  2725.  *  Parameters: const char *buffer, size_t size, int32_t *codepoint
  2726.  *
  2727.  *  Return: size_t
  2728.  *            
  2729.  *----------------------------------------------------------------------------*/
  2730. size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)
  2731. {
  2732.     size_t i;
  2733.     int32_t value = 0;
  2734.     unsigned char u = (unsigned char)buffer[0];
  2735.  
  2736.     if (size == 2) {
  2737.         value = u & 0x1F;
  2738.     } else if (size == 3) {
  2739.         value = u & 0xF;
  2740.     } else if (size == 4) {
  2741.         value = u & 0x7;
  2742.     } else
  2743.         return 0;
  2744.  
  2745.     for (i = 1; i < size; i++) {
  2746.         u = (unsigned char)buffer[i];
  2747.  
  2748.         if (u < 0x80 || u > 0xBF) {
  2749.             /* not a continuation byte */
  2750.             return 0;
  2751.         }
  2752.  
  2753.         value = (value << 6) + (u & 0x3F);
  2754.     }
  2755.  
  2756.     if (value > 0x10FFFF) {
  2757.         /* not in Unicode range */
  2758.         return 0;
  2759.     }
  2760.  
  2761.     else if (0xD800 <= value && value <= 0xDFFF) {
  2762.         /* invalid code point (UTF-16 surrogate halves) */
  2763.         return 0;
  2764.     }
  2765.  
  2766.     else if ((size == 2 && value < 0x80) || (size == 3 && value < 0x800) ||
  2767.              (size == 4 && value < 0x10000)) {
  2768.         /* overlong encoding */
  2769.         return 0;
  2770.     }
  2771.  
  2772.     if (codepoint)
  2773.         *codepoint = value;
  2774.  
  2775.     return 1;
  2776. }
  2777. /*-----------------------------------------------------------------------------
  2778.  *  utf8_iterate():  utf8 encoding
  2779.  *
  2780.  *  Parameters: const char *buffer, size_t bufsize, int32_t *codepoint
  2781.  *
  2782.  *  Return: const char *
  2783.  *            
  2784.  *----------------------------------------------------------------------------*/
  2785. const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)
  2786. {
  2787.     size_t count;
  2788.     int32_t value;
  2789.  
  2790.     if (!bufsize)
  2791.         return buffer;
  2792.  
  2793.     count = utf8_check_first(buffer[0]);
  2794.     if (count <= 0)
  2795.         return NULL;
  2796.  
  2797.     if (count == 1)
  2798.         value = (unsigned char)buffer[0];
  2799.     else {
  2800.         if (count > bufsize || !utf8_check_full(buffer, count, &value))
  2801.             return NULL;
  2802.     }
  2803.  
  2804.     if (codepoint)
  2805.         *codepoint = value;
  2806.  
  2807.     return buffer + count;
  2808. }
  2809. /*-----------------------------------------------------------------------------
  2810.  *  utf8_check_string():  utf8 encoding
  2811.  *
  2812.  *  Parameters: const char *string, size_t length
  2813.  *
  2814.  *  Return: int16_t
  2815.  *            
  2816.  *----------------------------------------------------------------------------*/
  2817. int16_t utf8_check_string(const char *string, size_t length)
  2818. {
  2819.     size_t i;
  2820.  
  2821.     for (i = 0; i < length; i++) {
  2822.         size_t count = utf8_check_first(string[i]);
  2823.         if (count == 0)
  2824.             return 0;
  2825.         else if (count > 1) {
  2826.             if (count > length - i)
  2827.                 return 0;
  2828.  
  2829.             if (!utf8_check_full(&string[i], count, NULL))
  2830.                 return 0;
  2831.  
  2832.             i += count - 1;
  2833.         }
  2834.     }
  2835.  
  2836.     return 1;
  2837. }
  2838. /*-----------------------------------------------------------------------------
  2839.  *  encode_utf8:  encode utf8
  2840.  *
  2841.  *  Parameters: uint8_t  *out, uint32_t in
  2842.  *
  2843.  *  Return: int16_t
  2844.  *            
  2845.  *----------------------------------------------------------------------------*/
  2846. int16_t encode_utf8(uint8_t  *out, uint32_t in)
  2847. {
  2848.   if(in < 0x80)
  2849.   {
  2850.     if(out != NULL)
  2851.       *out++ = in;
  2852.     return 1;
  2853.   }
  2854.   else if(in < 0x800)
  2855.   {
  2856.     if(out != NULL)
  2857.     {
  2858.       *out++ = (in >> 6) + 0xC0;
  2859.       *out++ = (in & 0x3F) + 0x80;
  2860.     }
  2861.     return 2;
  2862.   }
  2863.   else if(in < 0x10000)
  2864.   {
  2865.     if(out != NULL)
  2866.     {
  2867.       *out++ = (in >> 12) + 0xE0;
  2868.       *out++ = ((in >> 6) & 0x3F) + 0x80;
  2869.       *out++ = (in & 0x3F) + 0x80;
  2870.     }
  2871.     return 3;
  2872.   }
  2873.   else if(in < 0x110000)
  2874.   {
  2875.     if(out != NULL)
  2876.     {
  2877.       *out++ = (in >> 18) + 0xF0;
  2878.       *out++ = ((in >> 12) & 0x3F) + 0x80;
  2879.       *out++ = ((in >> 6) & 0x3F) + 0x80;
  2880.       *out++ = (in & 0x3F) + 0x80;
  2881.     }
  2882.     return 4;
  2883.   }
  2884.  
  2885.   return -1;
  2886. }
  2887. /*-----------------------------------------------------------------------------
  2888.  *  utf16_to_utf32:  utf16 to utf32
  2889.  *
  2890.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  2891.  *
  2892.  *  Return: size_t
  2893.  *            
  2894.  *----------------------------------------------------------------------------*/
  2895. size_t utf16_to_utf32(uint32_t  *out, const uint16_t *in, size_t len)
  2896. {
  2897.   size_t  rc = 0;
  2898.   int16_t  units;
  2899.   uint32_t code1;
  2900.  
  2901.   do
  2902.   {
  2903.     units = decode_utf16(&code1, in);
  2904.     if(units == -1)
  2905.       return -1;
  2906.  
  2907.     if(code1 > 0)
  2908.     {
  2909.       in += units;
  2910.  
  2911.       if(out != NULL)
  2912.       {
  2913.         if(rc < len)
  2914.           *out++ = code1;
  2915.       }
  2916.  
  2917.       if(SSIZE_MAX - 1 >= rc)
  2918.         ++rc;
  2919.       else
  2920.         return -1;
  2921.     }
  2922.   } while(code1 > 0);
  2923.  
  2924.   return rc;
  2925. }
  2926.  
  2927. /*-----------------------------------------------------------------------------
  2928.  *  utf16_to_utf8:  utf16 to utf8
  2929.  *
  2930.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  2931.  *
  2932.  *  Return: size_t
  2933.  *            
  2934.  *----------------------------------------------------------------------------*/
  2935. size_t utf16_to_utf8(uint8_t *out, const uint16_t *in, size_t len)
  2936. {
  2937.   size_t  rc = 0;
  2938.   int16_t  units;
  2939.   uint32_t code1;
  2940.   uint8_t  encoded[4];
  2941.  
  2942.   do
  2943.   {
  2944.     units = decode_utf16(&code1, in);
  2945.     if(units == -1)
  2946.       return -1;
  2947.  
  2948.     if(code1 > 0)
  2949.     {
  2950.       in += units;
  2951.  
  2952.       units = encode_utf8(encoded, code1);
  2953.       if(units == -1)
  2954.         return -1;
  2955.  
  2956.       if(out != NULL)
  2957.       {
  2958.         if(rc + units <= len)
  2959.         {
  2960.           *out++ = encoded[0];
  2961.           if(units > 1)
  2962.             *out++ = encoded[1];
  2963.           if(units > 2)
  2964.             *out++ = encoded[2];
  2965.           if(units > 3)
  2966.             *out++ = encoded[3];
  2967.         }
  2968.       }
  2969.  
  2970.       if(SSIZE_MAX - units >= rc)
  2971.         rc += units;
  2972.       else
  2973.         return -1;
  2974.     }
  2975.   } while(code1 > 0);
  2976.  
  2977.   return rc;
  2978. }
  2979.  
  2980. /*-----------------------------------------------------------------------------
  2981.  *  utf32_to_utf16:  utf32 to utf16
  2982.  *
  2983.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  2984.  *
  2985.  *  Return: size_t
  2986.  *            
  2987.  *----------------------------------------------------------------------------*/
  2988. size_t utf32_to_utf16(uint16_t *out, const uint32_t *in,  size_t len)
  2989. {
  2990.   size_t  rc = 0;
  2991.   int16_t  units;
  2992.   uint16_t encoded[2];
  2993.  
  2994.   while(*in > 0)
  2995.   {
  2996.     units = encode_utf16(encoded, *in++);
  2997.     if(units == -1)
  2998.       return -1;
  2999.  
  3000.     if(out != NULL)
  3001.     {
  3002.       if(rc + units <= len)
  3003.       {
  3004.         *out++ = encoded[0];
  3005.         if(units > 1)
  3006.           *out++ = encoded[1];
  3007.       }
  3008.     }
  3009.  
  3010.     if(SSIZE_MAX - units >= rc)
  3011.       rc += units;
  3012.     else
  3013.       return -1;
  3014.   }
  3015.  
  3016.   return rc;
  3017. }
  3018.  
  3019. /*-----------------------------------------------------------------------------
  3020.  *  utf32_to_utf8:  utf32 to utf8
  3021.  *
  3022.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  3023.  *
  3024.  *  Return: size_t
  3025.  *            
  3026.  *----------------------------------------------------------------------------*/
  3027. size_t utf32_to_utf8(uint8_t *out, const uint32_t *in, size_t len)
  3028. {
  3029.   size_t  rc = 0;
  3030.   int16_t  units;
  3031.   uint8_t  encoded[4];
  3032.  
  3033.   while(*in > 0)
  3034.   {
  3035.     units = encode_utf8(encoded, *in++);
  3036.     if(units == -1)
  3037.       return -1;
  3038.  
  3039.     if(out != NULL)
  3040.     {
  3041.       if(rc + units <= len)
  3042.       {
  3043.         *out++ = encoded[0];
  3044.         if(units > 1)
  3045.           *out++ = encoded[1];
  3046.         if(units > 2)
  3047.           *out++ = encoded[2];
  3048.         if(units > 3)
  3049.           *out++ = encoded[3];
  3050.       }
  3051.     }
  3052.  
  3053.     if(SSIZE_MAX - units >= rc)
  3054.       rc += units;
  3055.     else
  3056.       return -1;
  3057.   }
  3058.  
  3059.   return rc;
  3060. }
  3061.  
  3062. /*-----------------------------------------------------------------------------
  3063.  *  utf8_to_utf16:  utf8 to utf16
  3064.  *
  3065.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  3066.  *
  3067.  *  Return: size_t
  3068.  *            
  3069.  *----------------------------------------------------------------------------*/
  3070. size_t utf8_to_utf16(uint16_t *out, const uint8_t *in, size_t len)
  3071. {
  3072.   size_t  rc = 0;
  3073.   int16_t  units;
  3074.   uint32_t code1;
  3075.   uint16_t encoded[2];
  3076.  
  3077.   do
  3078.   {
  3079.     units = decode_utf8(&code1, in);
  3080.     if(units == -1)
  3081.       return -1;
  3082.  
  3083.     if(code1 > 0)
  3084.     {
  3085.       in += units;
  3086.  
  3087.       units = encode_utf16(encoded, code1);
  3088.       if(units == -1)
  3089.         return -1;
  3090.  
  3091.       if(out != NULL)
  3092.       {
  3093.         if(rc + units <= len)
  3094.         {
  3095.           *out++ = encoded[0];
  3096.           if(units > 1)
  3097.             *out++ = encoded[1];
  3098.         }
  3099.       }
  3100.  
  3101.       if(SSIZE_MAX - units >= rc)
  3102.         rc += units;
  3103.       else
  3104.         return -1;
  3105.     }
  3106.   } while(code1 > 0);
  3107.  
  3108.   return rc;
  3109. }
  3110.  
  3111. /*-----------------------------------------------------------------------------
  3112.  *  utf8_to_utf32:  utf8 to utf32
  3113.  *
  3114.  *  Parameters: uint32_t  *out, const uint16_t *in, size_t len
  3115.  *
  3116.  *  Return: size_t
  3117.  *            
  3118.  *----------------------------------------------------------------------------*/
  3119. size_t utf8_to_utf32(uint32_t *out, const uint8_t *in, size_t len)
  3120. {
  3121.   size_t  rc = 0;
  3122.   int16_t  units;
  3123.   uint32_t code1;
  3124.  
  3125.   do
  3126.   {
  3127.     units = decode_utf8(&code1, in);
  3128.     if(units == -1)
  3129.       return -1;
  3130.  
  3131.     if(code1 > 0)
  3132.     {
  3133.       in += units;
  3134.  
  3135.       if(out != NULL)
  3136.       {
  3137.         if(rc < len)
  3138.           *out++ = code1;
  3139.       }
  3140.  
  3141.       if(SSIZE_MAX - 1 >= rc)
  3142.         ++rc;
  3143.       else
  3144.         return -1;
  3145.     }
  3146.   } while(code1 > 0);
  3147.  
  3148.   return rc;
  3149. }
  3150. /*
  3151.  *  vigeners cipher ref :- https://golangify.com/shifr-vizhenera
  3152.  *  Vasile Buldumac vasile.buldumac@ati.utm.md
  3153.  *  Ported from Golang to mikroE C ACP Aviation
  3154. */
  3155.  
  3156. /*-----------------------------------------------------------------------------
  3157.  *  vigenersCipherEncode:  vigeners cipher encode
  3158.  *
  3159.  *  Parameters: char* cipherText, char* keyword, char* message
  3160.  *
  3161.  *  Return: void
  3162.  *            
  3163.  *----------------------------------------------------------------------------*/
  3164. void vigenersCipherEncode( char* cipherText, char* keyword, char* message  )
  3165. {
  3166.    uint8_t c;
  3167.    uint16_t keyIndex = 0;
  3168.    size_t i;
  3169.    uint8_t k;
  3170.      
  3171.    for (i = 0; i < strlen(cipherText); i++)
  3172.    {
  3173.       if (c >= 'A' && c <= 'Z')                                                 // A=0, B=1, ... Z=25
  3174.       {
  3175.            c = cipherText[i] - 'A';
  3176.            k = keyword[keyIndex] - 'A';
  3177.  
  3178.            c = (c-k+26)%26 + 'A';                                               // encrypted letter - key letter
  3179.            message[i] = c;
  3180.  
  3181.            keyIndex++;                                                          // increment keyIndex in range of keyword
  3182.            keyIndex %= strlen(keyword);
  3183.        }
  3184.        else if (c >= 'a' && c <= 'z')
  3185.        {
  3186.            c = cipherText[i] - 'a';
  3187.            k = keyword[keyIndex] - 'a';
  3188.  
  3189.            c = (c-k+26)%26 + 'a';                                               // encrypted letter - key letter
  3190.            message[i] = c;
  3191.  
  3192.            keyIndex++;                                                          // increment keyIndex in range of keyword
  3193.            keyIndex %= strlen(keyword);        
  3194.        }
  3195.    }
  3196. }
  3197.  
  3198. /*-----------------------------------------------------------------------------
  3199.  *  vigenersCipherDecode:  vieners cipher decode
  3200.  *
  3201.  *  Parameters: char* cipherText, char* keyword, char* message
  3202.  *
  3203.  *  Return: void
  3204.  *            
  3205.  *----------------------------------------------------------------------------*/
  3206. void vigenersCipherDecode( char* cipherText, char* keyword, char* message  )
  3207. {
  3208.    uint8_t c;
  3209.    uint16_t keyIndex = 0;
  3210.    size_t i;
  3211.    uint8_t k;
  3212.      
  3213.    for (i = 0; i < strlen(message); i++)
  3214.    {
  3215.       c = message[i];
  3216.       if (c >= 'A' && c <= 'Z')
  3217.       {
  3218.         c -= 'A';                                                               // A=0, B=1, ... Z=25
  3219.         k = keyword[keyIndex] - 'A';
  3220.  
  3221.         c = (c+k)%26 + 'A';                                                     // encrypted letter - key letter
  3222.  
  3223.         keyIndex++;                                                             // increment keyIndex in range of keyword
  3224.         keyIndex %= strlen(keyword);
  3225.       }
  3226.       else if (c >= 'a' && c <= 'z')
  3227.       {
  3228.         c -= 'a';                                                               // A=0, B=1, ... Z=25
  3229.         k = keyword[keyIndex] - 'a';
  3230.  
  3231.         c = (c+k)%26 + 'a';                                                     // encrypted letter - key letter
  3232.  
  3233.         keyIndex++;                                                             // increment keyIndex in range of keyword
  3234.         keyIndex %= strlen(keyword);      
  3235.       }
  3236.       cipherText[i] = c;
  3237.    }
  3238. }
  3239.  
  3240. /*-----------------------------------------------------------------------------
  3241.  *  rot13CipherEncode:  rot13 cipher encode
  3242.  *
  3243.  *  Parameters: char* cipherText, char* keyword, char* message
  3244.  *
  3245.  *  Return: void
  3246.  *            
  3247.  *----------------------------------------------------------------------------*/
  3248. void rot13CipherEncode( char* cipherText, char* keyword, char* message  )
  3249. {
  3250.    uint8_t c;
  3251.    size_t i;
  3252.      
  3253.    for (i = 0; i < strlen(cipherText); i++)
  3254.    {
  3255.     c = cipherText[i];
  3256.         if (c >= 'a' && c <= 'z')
  3257.         {
  3258.            c = c + 13;
  3259.            if (c > 'z')
  3260.            {
  3261.               c = c - 26;
  3262.            }
  3263.         }
  3264.         else if (c >= 'A' && c <= 'Z')
  3265.         {
  3266.             c = c + 13;
  3267.             if (c > 'Z')
  3268.             {
  3269.                c = c - 26;
  3270.             }
  3271.         }
  3272.         message[i] = c;
  3273.     }
  3274. }
  3275.  
  3276. /*-----------------------------------------------------------------------------
  3277.  *  rot13CipherDecode:  rot13 cipher decode
  3278.  *
  3279.  *  Parameters: char* cipherText, char* keyword, char* message
  3280.  *
  3281.  *  Return: void
  3282.  *            
  3283.  *----------------------------------------------------------------------------*/
  3284. void rot13CipherDecode( char* cipherText, char* keyword, char* message  )
  3285. {
  3286.    uint8_t c;
  3287.    size_t i;
  3288.      
  3289.    for (i = 0; i < strlen(message); i++)
  3290.    {
  3291.       c = message[i];
  3292.       if (c >= 'a' && c <= 'z')
  3293.       {
  3294.         c -= 13;
  3295.         if (c < 'a')
  3296.         {
  3297.             c += 26;
  3298.         }
  3299.       }
  3300.       else if (c >= 'A' && c <= 'Z')
  3301.       {
  3302.         c -= 13;
  3303.         if (c < 'A')
  3304.         {
  3305.             c += 26;
  3306.         }
  3307.       }
  3308.       cipherText[i] = c;
  3309.    }
  3310. }
  3311. #ifdef __cplusplus
  3312. }
  3313. #endif
Add Comment
Please, Sign In to add comment