1+ /*
2+ Copyright (c) 2024, VeriSign, Inc.
3+ All rights reserved.
4+
5+ Redistribution and use in source and binary forms, with or without
6+ modification, are permitted (subject to the limitations in the disclaimer
7+ below) provided that the following conditions are met:
8+
9+ * Redistributions of source code must retain the above copyright notice,
10+ this list of conditions and the following disclaimer.
11+
12+ * Redistributions in binary form must reproduce the above copyright
13+ notice, this list of conditions and the following disclaimer in the
14+ documentation and/or other materials provided with the distribution.
15+
16+ * Neither the name of the copyright holder nor the names of its
17+ contributors may be used to endorse or promote products derived from this
18+ software without specific prior written permission.
19+
20+ NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
21+ THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
25+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+ POSSIBILITY OF SUCH DAMAGE.
32+ */
33+ #include <string.h>
34+ #include <stdint.h>
35+ #include <stdio.h>
36+ #include <ctype.h>
37+
38+ #include "mtl_util.h"
39+ #include "mtltool.h"
40+ #include "mtlverify.h"
41+ #include "mtl_example_util.h"
42+
43+ #include <openssl/evp.h>
44+
45+
46+ /*****************************************************************
47+ * Get Underlying Signature
48+ ******************************************************************
49+ * @param algo_str, C character string representing the algorithm
50+ * @return ALGORITHM structure element with the properties for
51+ * the specific algorithm, or NULL if not found
52+ */
53+ ALGORITHM * get_underlying_signature (char * algo_str , ALGORITHM * algos )
54+ {
55+ uint16_t algo_idx = 0 ;
56+
57+ while (algos [algo_idx ].name != NULL ) {
58+ if (strcmp (algos [algo_idx ].name , (char * )algo_str ) == 0 ) {
59+ return & algos [algo_idx ];
60+ }
61+ algo_idx ++ ;
62+ }
63+
64+ return NULL ;
65+ }
66+
67+
68+
69+ /*****************************************************************
70+ * Convert a string to upper case in place
71+ ******************************************************************
72+ * @param data, string to convert (in place)
73+ * @return Converted string pointer
74+ */
75+ char * mtl_str2upper (char * data )
76+ {
77+ char * p = data ;
78+
79+ for (; * p ; ++ p )
80+ * p = toupper (* p );
81+ return data ;
82+ }
83+
84+
85+
86+ /*****************************************************************
87+ * Convert an encoded buffer to the binary in memory format
88+ ******************************************************************
89+ * @param input encoded input buffer
90+ * @param input_len length of the encoded input buffer
91+ * @param output pointer for the output buffer (user frees)
92+ * @param encoding format the input buffer is using
93+ * @return size of the output buffer
94+ */
95+ size_t mtl_buffer2bin (uint8_t * input , size_t input_len , uint8_t * * output , data_encoding encoding ) {
96+ uint8_t * buffer = NULL ;
97+ size_t buffer_size ;
98+ uint8_t byte_val ;
99+ char tmp [3 ];
100+ int b64_len ;
101+ uint8_t b64_buff [MAX_BUFFER_SIZE ];
102+ EVP_ENCODE_CTX * ctx = NULL ;
103+ int status ;
104+
105+ if (input_len >= MAX_BUFFER_SIZE ) {
106+ LOG_ERROR ("Invalid input length, greater than the buffer size" );
107+ * output = NULL ;
108+ return 0 ;
109+ }
110+
111+ if (encoding == BASE64_STRING ) {
112+ ctx = EVP_ENCODE_CTX_new ();
113+
114+ EVP_DecodeInit (ctx );
115+ status = EVP_DecodeUpdate (ctx , & b64_buff [0 ], & b64_len , input , input_len );
116+ if ((status != 0 ) && (status != 1 )) {
117+ * output = NULL ;
118+ EVP_ENCODE_CTX_free (ctx );
119+ return 0 ;
120+ }
121+ buffer_size = b64_len ;
122+ status = EVP_DecodeFinal (ctx , & b64_buff [b64_len ], & b64_len );
123+ if (status != 1 ) {
124+ * output = NULL ;
125+ EVP_ENCODE_CTX_free (ctx );
126+ return 0 ;
127+ }
128+ buffer_size += b64_len ;
129+ buffer = calloc (1 , buffer_size );
130+ memcpy (buffer , & b64_buff [0 ], buffer_size );
131+ EVP_ENCODE_CTX_free (ctx );
132+ } else {
133+ if (input_len % 2 != 0 ) {
134+ * output = NULL ;
135+ return 0 ;
136+ }
137+ buffer_size = input_len /2 ;
138+
139+ for (size_t i = 0 ; i < input_len ; i += 2 ) {
140+ tmp [0 ] = input [i ];
141+ tmp [1 ] = input [i + 1 ];
142+ tmp [2 ] = '\0' ;
143+ if (sscanf (tmp , "%hhx" , & byte_val ) != 1 ) {
144+ * output = NULL ;
145+ return 0 ;
146+ }
147+ b64_buff [i /2 ] = byte_val ;
148+ }
149+ buffer = calloc (1 , buffer_size );
150+ memcpy (buffer , & b64_buff [0 ], buffer_size );
151+ }
152+ * output = buffer ;
153+ return buffer_size ;
154+ }
155+
156+ static void verbose_print_block (char * descript , FILE * stream ) {
157+ uint32_t len = 45 - strlen (descript );
158+ uint32_t i = 0 ;
159+
160+ if (strlen (descript ) == 0 ) {
161+ fprintf (stream , " ========" );
162+ for (i = 0 ; i < len + 2 ; i ++ ) {
163+ fprintf (stream , "=" );
164+ }
165+ fprintf (stream ," \n\n" );
166+ } else {
167+ fprintf (stream ," ======== %s " , descript );
168+ for (i = 0 ; i < len ; i ++ ) {
169+ fprintf (stream ,"=" );
170+ }
171+ fprintf (stream ," \n" );
172+ }
173+ }
174+
175+
176+ static void verbose_print_buffer (char * descript , uint8_t * buffer , uint32_t buffer_len , FILE * stream ) {
177+ uint32_t i = 0 ;
178+
179+ fprintf (stream , " %15s - " , descript );
180+ for (i = 0 ; i < buffer_len ; i ++ ) {
181+ fprintf (stream , "%02x" , buffer [i ]);
182+ }
183+ fprintf (stream , "\n" );
184+ }
185+
186+
187+ static void verbose_print_hex (char * descript , uint32_t value , FILE * stream ) {
188+ fprintf (stream , " %15s - %02x\n" , descript , value );
189+ }
190+
191+ static void verbose_print_number (char * descript , uint32_t value , FILE * stream ) {
192+ fprintf (stream , " %15s - %02d\n" , descript , value );
193+ }
194+
195+ static void verbose_print_string (char * descript , char * str , FILE * stream ) {
196+ fprintf (stream , " %15s - %s\n" , descript , str );
197+ }
198+
199+ static void verbose_print_rung (char * descript , uint32_t l , uint32_t r , uint8_t * buffer , uint32_t buffer_len , FILE * stream ) {
200+ uint32_t i = 0 ;
201+
202+ fprintf (stream , " %15s (%d,%d) " , descript , l , r );
203+ for (i = 0 ; i < buffer_len ; i ++ ) {
204+ fprintf (stream , "%02x" , buffer [i ]);
205+ }
206+ fprintf (stream , "\n" );
207+ }
208+
209+
210+ void mtl_print_auth_path (AUTHPATH * auth_path , RANDOMIZER * mtl_rand , uint32_t hash_len , FILE * stream ) {
211+ uint32_t hash ;
212+
213+ if (stream != NULL ) {
214+ if (auth_path != NULL ) {
215+ verbose_print_block ("Authentication Path" , stream );
216+ if (mtl_rand != NULL ) {
217+ verbose_print_buffer ("Randomizer" , mtl_rand -> value , hash_len , stream );
218+ }
219+ verbose_print_hex ("Flags" , auth_path -> flags , stream );
220+ verbose_print_buffer ("SID" , auth_path -> sid .id , auth_path -> sid .length , stream );
221+ verbose_print_number ("Leaf Index" , auth_path -> leaf_index , stream );
222+ verbose_print_number ("Left Rung" , auth_path -> rung_left , stream );
223+ verbose_print_number ("Right Rung" , auth_path -> rung_right , stream );
224+ verbose_print_number ("Hash Count" , auth_path -> sibling_hash_count , stream );
225+ for (hash = 0 ; hash < auth_path -> sibling_hash_count ; hash ++ ) {
226+ verbose_print_buffer ("Path Hash" , & auth_path -> sibling_hash [hash * hash_len ], hash_len , stream );
227+ }
228+ verbose_print_block ("" , stream );
229+ }
230+ }
231+ }
232+
233+ void mtl_print_ladder (LADDER * ladder , FILE * stream ) {
234+ RUNG * r = NULL ;
235+ uint16_t rc = 0 ;
236+
237+ if (stream != NULL ) {
238+ verbose_print_block ("Ladder Values" , stream );
239+ verbose_print_hex ("Flags" , ladder -> flags , stream );
240+ verbose_print_buffer ("SID" , ladder -> sid .id , ladder -> sid .length , stream );
241+ verbose_print_number ("Rung Count" , ladder -> rung_count , stream );
242+ for (rc = 0 ; rc < ladder -> rung_count ; rc ++ ) {
243+ r = (RUNG * ) ((uint8_t * ) ladder -> rungs + (sizeof (RUNG ) * rc ));
244+ verbose_print_rung ("Ladder Rung" , r -> left_index , r -> right_index , r -> hash , r -> hash_length , stream );
245+ }
246+ verbose_print_block ("" , stream );
247+ }
248+ }
249+
250+ void mtl_print_ladder_signature (uint8_t * sig , size_t sig_len , FILE * stream ) {
251+ if (stream != NULL ) {
252+ verbose_print_block ("Ladder Signature" , stream );
253+ verbose_print_number ("Signature Len" , sig_len , stream );
254+ verbose_print_buffer ("Signature" , sig , sig_len , stream );
255+ verbose_print_block ("" , stream );
256+ }
257+ }
258+
259+ void mtl_print_rung (RUNG * rung , FILE * stream ) {
260+ if (stream != NULL ) {
261+ verbose_print_block ("Ladder Rung Values" , stream );
262+ verbose_print_rung ("Ladder Rung" , rung -> left_index , rung -> right_index , rung -> hash , rung -> hash_length , stream );
263+ verbose_print_block ("" , stream );
264+ }
265+ }
266+
267+
268+ void mtl_print_message (uint8_t * message , uint32_t message_len , FILE * stream ) {
269+ if (stream != NULL ) {
270+ verbose_print_block ("Signature Message" , stream );
271+ verbose_print_number ("Msg Length" , message_len , stream );
272+ verbose_print_buffer ("Msg Bytes" , message , message_len , stream );
273+ verbose_print_block ("" , stream );
274+ }
275+ }
276+
277+
278+ void mtl_print_signature_scheme (ALGORITHM * algo , FILE * stream ) {
279+ if (stream != NULL ) {
280+ verbose_print_block ("MTL Signature Scheme" , stream );
281+ verbose_print_string ("Scheme" , algo -> name , stream );
282+ verbose_print_number ("Security Param" , algo -> sec_param , stream );
283+ verbose_print_number ("NIST Level" , algo -> nist_level , stream );
284+ verbose_print_hex ("Randomizing" , algo -> randomize , stream );
285+ verbose_print_hex ("Robust" , algo -> robust , stream );
286+ verbose_print_string ("Underlying Sig" , algo -> oqs_str , stream );
287+ verbose_print_number ("OID Length" , algo -> oid_len , stream );
288+ verbose_print_buffer ("OID Value" , algo -> oid , algo -> oid_len , stream );
289+ verbose_print_block ("" , stream );
290+ }
291+ }
292+
293+ void mtl_print_mtl_buffer (char * label , uint8_t * buffer , uint32_t buffer_length , FILE * stream ) {
294+ if (stream != NULL ) {
295+ verbose_print_block (label , stream );
296+ verbose_print_number ("Length" , buffer_length , stream );
297+ verbose_print_buffer ("Value" , buffer , buffer_length , stream );
298+ verbose_print_block ("" , stream );
299+ }
300+ }
0 commit comments