1 /*############################################################################
2 # Copyright 2016-2017 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 ############################################################################*/
16
17 /*!
18 * \file
19 * \brief Print helper implementation.
20 */
21 #ifndef EPID_ENABLE_DEBUG_PRINT
22 #define EPID_ENABLE_DEBUG_PRINT
23 #endif
24
25 #include "epid/common/math/printutils.h"
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "epid/common/math/src/bignum-internal.h"
31 #include "epid/common/math/src/ecgroup-internal.h"
32 #include "epid/common/math/src/finitefield-internal.h"
33 #include "epid/common/src/memory.h"
34 #include "ext/ipp/include/ippcp.h"
35
36 /// Allowed number of characters printed in one line
37 #define WIDTH 49
38
39 /// Amount of identation added in the beginning of each line
40 #define INDENT 2
41
42 /// Number of charaters used to represent one byte. For example, "ab" or "05".
43 #define BYTE_LENGTH 2
44
45 /// Separator
46 #define SEPARATOR (" ")
47
48 /// Make configured number of identation
49 #define MAKE_INDENT() \
50 { \
51 uint8_t ind = 0; \
52 for (ind = 0; ind < INDENT; ind++) { \
53 PRINT(" "); \
54 } \
55 }
56
57 /// Print to specified stream
58 #define PRINT(...) fprintf(stdout, __VA_ARGS__)
59
PrintBuf(ConstOctStr buf,size_t size)60 static int PrintBuf(ConstOctStr buf, size_t size) {
61 size_t curr_column = 0;
62 size_t i = 0;
63 if (!buf || size == 0) {
64 return -1;
65 }
66 for (i = 0; i < size; i++) {
67 if (curr_column == 0) {
68 MAKE_INDENT();
69 curr_column += INDENT;
70 }
71 if (BYTE_LENGTH != PRINT("%.2x", ((unsigned char const*)buf)[i])) {
72 return -1;
73 }
74 curr_column += BYTE_LENGTH;
75 if (i < size - 1) {
76 if ((curr_column + BYTE_LENGTH + strlen(SEPARATOR)) > WIDTH) {
77 PRINT("\n");
78 curr_column = 0;
79 } else {
80 PRINT("%s", SEPARATOR);
81 curr_column += (uint8_t)strlen(SEPARATOR);
82 }
83 }
84 }
85 PRINT("\n");
86 return 0;
87 }
88
PrintBigNum(BigNum const * big_num,char const * var_name)89 void PrintBigNum(BigNum const* big_num, char const* var_name) {
90 IppStatus sts = ippStsNoErr;
91 unsigned char* buf = NULL;
92 int ipp_word_buf_size;
93 if (!var_name) {
94 var_name = "<no name>";
95 }
96 PRINT("%s (BigNum):\n", var_name);
97 if (!big_num) {
98 MAKE_INDENT();
99 PRINT("<null>\n");
100 return;
101 }
102 if (!big_num->ipp_bn) {
103 MAKE_INDENT();
104 PRINT("<invalid>\n");
105 return;
106 }
107 sts = ippsGetSize_BN(big_num->ipp_bn, &ipp_word_buf_size);
108 if (ippStsNoErr != sts) {
109 MAKE_INDENT();
110 PRINT("<invalid>\n");
111 return;
112 }
113 do {
114 buf = SAFE_ALLOC(ipp_word_buf_size * sizeof(Ipp32u));
115 if (!buf) {
116 MAKE_INDENT();
117 PRINT("<invalid>\n");
118 break;
119 }
120 sts = ippsGetOctString_BN((OctStr)buf, ipp_word_buf_size * sizeof(Ipp32u),
121 big_num->ipp_bn);
122 if (ippStsNoErr != sts) {
123 MAKE_INDENT();
124 PRINT("<invalid>\n");
125 break;
126 }
127 if (0 != PrintBuf((ConstOctStr)buf, ipp_word_buf_size * sizeof(Ipp32u))) {
128 MAKE_INDENT();
129 PRINT("<invalid>\n");
130 break;
131 }
132 } while (0);
133
134 SAFE_FREE(buf);
135 }
136
PrintFfElement(FiniteField const * ff,FfElement const * ff_element,char const * var_name,PrintUtilFormat format)137 void PrintFfElement(FiniteField const* ff, FfElement const* ff_element,
138 char const* var_name, PrintUtilFormat format) {
139 IppStatus sts;
140 uint8_t ff_element_str[sizeof(Fq12ElemStr)];
141 int ipp_ff_element_size;
142 if (!var_name) {
143 var_name = "<no name>";
144 }
145 if (!ff_element || !ff) {
146 PRINT("%s (FfElement):\n", var_name);
147 MAKE_INDENT();
148 PRINT("<null>\n");
149 return;
150 }
151 if (!ff_element->ipp_ff_elem || !ff->ipp_ff ||
152 (format != kPrintUtilUnannotated && format != kPrintUtilAnnotated)) {
153 PRINT("%s (FfElement):\n", var_name);
154 MAKE_INDENT();
155 PRINT("<invalid>\n");
156 return;
157 }
158
159 // get the data
160 ipp_ff_element_size = ff_element->element_len * sizeof(Ipp32u);
161 sts = ippsGFpGetElementOctString(ff_element->ipp_ff_elem,
162 (OctStr)&ff_element_str, ipp_ff_element_size,
163 ff->ipp_ff);
164 if (ippStsNoErr != sts) {
165 PRINT("%s (FfElement):\n", var_name);
166 MAKE_INDENT();
167 PRINT("<invalid>\n");
168 return;
169 }
170
171 if (ipp_ff_element_size == sizeof(FqElemStr)) {
172 PrintFqElemStr((const FqElemStr*)&ff_element_str, var_name);
173 } else if (ipp_ff_element_size == sizeof(FpElemStr)) {
174 PrintFpElemStr((const FpElemStr*)&ff_element_str, var_name);
175 } else if (ipp_ff_element_size == sizeof(Fq2ElemStr)) {
176 PrintFq2ElemStr((const Fq2ElemStr*)&ff_element_str, var_name, format);
177 } else if (ipp_ff_element_size == sizeof(Fq6ElemStr)) {
178 PrintFq6ElemStr((const Fq6ElemStr*)&ff_element_str, var_name, format);
179 } else if (ipp_ff_element_size == sizeof(Fq6ElemStr)) {
180 PrintFq12ElemStr((const Fq12ElemStr*)&ff_element_str, var_name, format);
181 } else if (ipp_ff_element_size == sizeof(GtElemStr)) {
182 PrintGtElemStr((const GtElemStr*)&ff_element_str, var_name, format);
183 } else {
184 PRINT("%s (FfElement):\n", var_name);
185 MAKE_INDENT();
186 PRINT("<invalid>\n");
187 }
188 }
189
PrintEcPoint(EcGroup const * g,EcPoint const * ec_point,char const * var_name,PrintUtilFormat format)190 void PrintEcPoint(EcGroup const* g, EcPoint const* ec_point,
191 char const* var_name, PrintUtilFormat format) {
192 FiniteField* fp = NULL;
193 FfElement* fp_x = NULL;
194 FfElement* fp_y = NULL;
195 uint8_t ec_point_str[sizeof(G2ElemStr)];
196 if (!var_name) {
197 var_name = "<no name>";
198 }
199 if (!ec_point || !g) {
200 PRINT("%s (EcPoint):\n", var_name);
201 MAKE_INDENT();
202 PRINT("<null>\n");
203 return;
204 }
205 if (!ec_point->ipp_ec_pt || !g->ff || !g->ipp_ec) {
206 PRINT("%s (EcPoint):\n", var_name);
207 MAKE_INDENT();
208 PRINT("<invalid>\n");
209 return;
210 }
211 do {
212 IppStatus sts = ippStsNoErr;
213 int ipp_half_strlen;
214 // get finite field
215 fp = g->ff;
216
217 // create element X
218 if (kEpidNoErr != NewFfElement(fp, &fp_x)) {
219 PRINT("%s (EcPoint):\n", var_name);
220 MAKE_INDENT();
221 PRINT("<invalid>\n");
222 break;
223 }
224 // create element Y
225 if (kEpidNoErr != NewFfElement(fp, &fp_y)) {
226 PRINT("%s (EcPoint):\n", var_name);
227 MAKE_INDENT();
228 PRINT("<invalid>\n");
229 break;
230 }
231
232 ipp_half_strlen = fp_x->element_len * sizeof(Ipp32u);
233
234 // get elements from point
235 sts = ippsGFpECGetPoint(ec_point->ipp_ec_pt, fp_x->ipp_ff_elem,
236 fp_y->ipp_ff_elem, g->ipp_ec);
237 // check return codes
238 if (ippStsNoErr != sts) {
239 PRINT("%s (EcPoint):\n", var_name);
240 MAKE_INDENT();
241 PRINT("<invalid>\n");
242 break;
243 }
244
245 // get element X data
246 sts =
247 ippsGFpGetElementOctString(fp_x->ipp_ff_elem, (IppOctStr)&ec_point_str,
248 ipp_half_strlen, fp->ipp_ff);
249 // check return codes
250 if (ippStsNoErr != sts) {
251 PRINT("%s (EcPoint):\n", var_name);
252 MAKE_INDENT();
253 PRINT("<invalid>\n");
254 break;
255 }
256 // get element Y data
257 sts = ippsGFpGetElementOctString(fp_y->ipp_ff_elem,
258 (IppOctStr)&ec_point_str + ipp_half_strlen,
259 ipp_half_strlen, fp->ipp_ff);
260 // check return codes
261 if (ippStsNoErr != sts) {
262 PRINT("%s (EcPoint):\n", var_name);
263 MAKE_INDENT();
264 PRINT("<invalid>\n");
265 break;
266 }
267
268 if (2 * ipp_half_strlen == sizeof(G1ElemStr)) {
269 PrintG1ElemStr((const G1ElemStr*)&ec_point_str, var_name, format);
270 } else if (2 * ipp_half_strlen == sizeof(G2ElemStr)) {
271 PrintG2ElemStr((const G2ElemStr*)&ec_point_str, var_name, format);
272 } else {
273 PRINT("%s (EcPoint):\n", var_name);
274 MAKE_INDENT();
275 PRINT("<invalid>\n");
276 break;
277 }
278 } while (0);
279
280 DeleteFfElement(&fp_x);
281 DeleteFfElement(&fp_y);
282 }
283
PrintBigNumStr(BigNumStr const * big_num_str,char const * var_name)284 void PrintBigNumStr(BigNumStr const* big_num_str, char const* var_name) {
285 if (!var_name) {
286 var_name = "<no name>";
287 }
288 PRINT("%s (BigNumStr):\n", var_name);
289 if (!big_num_str) {
290 MAKE_INDENT();
291 PRINT("<null>\n");
292 return;
293 }
294 if (0 != PrintBuf((ConstOctStr)big_num_str, sizeof(*big_num_str))) {
295 MAKE_INDENT();
296 PRINT("<invalid>\n");
297 return;
298 }
299 }
300
PrintFpElemStr(FpElemStr const * fp_elem_str,char const * var_name)301 void PrintFpElemStr(FpElemStr const* fp_elem_str, char const* var_name) {
302 if (!var_name) {
303 var_name = "<no name>";
304 }
305 PRINT("%s (FpElemStr):\n", var_name);
306 if (!fp_elem_str) {
307 MAKE_INDENT();
308 PRINT("<null>\n");
309 return;
310 }
311 if (0 != PrintBuf((ConstOctStr)fp_elem_str, sizeof(*fp_elem_str))) {
312 MAKE_INDENT();
313 PRINT("<invalid>\n");
314 return;
315 }
316 }
317
PrintFqElemStr(FqElemStr const * fq_elem_str,char const * var_name)318 void PrintFqElemStr(FqElemStr const* fq_elem_str, char const* var_name) {
319 if (!var_name) {
320 var_name = "<no name>";
321 }
322 PRINT("%s (FqElemStr):\n", var_name);
323 if (!fq_elem_str) {
324 MAKE_INDENT();
325 PRINT("<null>\n");
326 return;
327 }
328 if (0 != PrintBuf((ConstOctStr)fq_elem_str, sizeof(*fq_elem_str))) {
329 MAKE_INDENT();
330 PRINT("<invalid>\n");
331 return;
332 }
333 }
334
PrintFq2ElemStr(Fq2ElemStr const * fq2_elem_str,char const * var_name,PrintUtilFormat format)335 void PrintFq2ElemStr(Fq2ElemStr const* fq2_elem_str, char const* var_name,
336 PrintUtilFormat format) {
337 if (!var_name) {
338 var_name = "<no name>";
339 }
340 PRINT("%s (Fq2ElemStr):\n", var_name);
341 if (!fq2_elem_str) {
342 MAKE_INDENT();
343 PRINT("<null>\n");
344 return;
345 }
346 if (format == kPrintUtilAnnotated) {
347 MAKE_INDENT();
348 PRINT("a0:\n");
349 if (0 != PrintBuf((ConstOctStr)&fq2_elem_str->a[0],
350 sizeof(fq2_elem_str->a[0]))) {
351 MAKE_INDENT();
352 PRINT("<invalid>\n");
353 return;
354 }
355 MAKE_INDENT();
356 PRINT("a1:\n");
357 if (0 != PrintBuf((ConstOctStr)&fq2_elem_str->a[1],
358 sizeof(fq2_elem_str->a[1]))) {
359 MAKE_INDENT();
360 PRINT("<invalid>\n");
361 return;
362 }
363 } else if (format == kPrintUtilUnannotated) {
364 if (0 != PrintBuf((ConstOctStr)fq2_elem_str, sizeof(*fq2_elem_str))) {
365 MAKE_INDENT();
366 PRINT("<invalid>\n");
367 return;
368 }
369 } else {
370 MAKE_INDENT();
371 PRINT("<invalid>\n");
372 return;
373 }
374 }
375
PrintFq6ElemStr(Fq6ElemStr const * fq6_elem_str,char const * var_name,PrintUtilFormat format)376 void PrintFq6ElemStr(Fq6ElemStr const* fq6_elem_str, char const* var_name,
377 PrintUtilFormat format) {
378 if (!var_name) {
379 var_name = "<no name>";
380 }
381 PRINT("%s (Fq6ElemStr):\n", var_name);
382 if (!fq6_elem_str) {
383 MAKE_INDENT();
384 PRINT("<null>\n");
385 return;
386 }
387 if (format == kPrintUtilAnnotated) {
388 unsigned int i = 0;
389 unsigned int j = 0;
390 for (i = 0; i < sizeof(fq6_elem_str->a) / sizeof(fq6_elem_str->a[0]); i++) {
391 for (j = 0;
392 j < sizeof(fq6_elem_str->a[0]) / sizeof(fq6_elem_str->a[0].a[0]);
393 j++) {
394 MAKE_INDENT();
395 PRINT("a%u.%u:\n", i, j);
396 if (0 != PrintBuf((ConstOctStr)&fq6_elem_str->a[i].a[j],
397 sizeof(fq6_elem_str->a[i].a[j]))) {
398 MAKE_INDENT();
399 PRINT("<invalid>\n");
400 return;
401 }
402 }
403 }
404 } else if (format == kPrintUtilUnannotated) {
405 if (0 != PrintBuf((ConstOctStr)fq6_elem_str, sizeof(*fq6_elem_str))) {
406 MAKE_INDENT();
407 PRINT("<invalid>\n");
408 return;
409 }
410 } else {
411 MAKE_INDENT();
412 PRINT("<invalid>\n");
413 return;
414 }
415 }
416
PrintFq12ElemStr(Fq12ElemStr const * fq12_elem_str,char const * var_name,PrintUtilFormat format)417 void PrintFq12ElemStr(Fq12ElemStr const* fq12_elem_str, char const* var_name,
418 PrintUtilFormat format) {
419 if (!var_name) {
420 var_name = "<no name>";
421 }
422 PRINT("%s (Fq12ElemStr):\n", var_name);
423 if (!fq12_elem_str) {
424 MAKE_INDENT();
425 PRINT("<null>\n");
426 return;
427 }
428 if (format == kPrintUtilAnnotated) {
429 unsigned int i = 0;
430 unsigned int j = 0;
431 unsigned int k = 0;
432 for (i = 0; i < sizeof(fq12_elem_str->a) / sizeof(fq12_elem_str->a[0]);
433 i++) {
434 for (j = 0;
435 j < sizeof(fq12_elem_str->a[0]) / sizeof(fq12_elem_str->a[0].a[0]);
436 j++) {
437 for (k = 0; k < sizeof(fq12_elem_str->a[0].a[0]) /
438 sizeof(fq12_elem_str->a[0].a[0].a[0]);
439 k++) {
440 MAKE_INDENT();
441 PRINT("a%u.%u.%u:\n", i, j, k);
442 if (0 != PrintBuf((ConstOctStr)&fq12_elem_str->a[i].a[j].a[k],
443 sizeof(fq12_elem_str->a[i].a[j].a[k]))) {
444 MAKE_INDENT();
445 PRINT("<invalid>\n");
446 return;
447 }
448 }
449 }
450 }
451 } else if (format == kPrintUtilUnannotated) {
452 if (0 != PrintBuf((ConstOctStr)fq12_elem_str, sizeof(*fq12_elem_str))) {
453 MAKE_INDENT();
454 PRINT("<invalid>\n");
455 return;
456 }
457 } else {
458 MAKE_INDENT();
459 PRINT("<invalid>\n");
460 return;
461 }
462 }
463
PrintG1ElemStr(G1ElemStr const * g1_elem_str,char const * var_name,PrintUtilFormat format)464 void PrintG1ElemStr(G1ElemStr const* g1_elem_str, char const* var_name,
465 PrintUtilFormat format) {
466 if (!var_name) {
467 var_name = "<no name>";
468 }
469 PRINT("%s (G1ElemStr):\n", var_name);
470 if (!g1_elem_str) {
471 MAKE_INDENT();
472 PRINT("<null>\n");
473 return;
474 }
475 if (format == kPrintUtilAnnotated) {
476 MAKE_INDENT();
477 PRINT("x:\n");
478 if (0 != PrintBuf((ConstOctStr)&g1_elem_str->x, sizeof(g1_elem_str->x))) {
479 MAKE_INDENT();
480 PRINT("<invalid>\n");
481 return;
482 }
483 MAKE_INDENT();
484 PRINT("y:\n");
485 if (0 != PrintBuf((ConstOctStr)&g1_elem_str->y, sizeof(g1_elem_str->y))) {
486 MAKE_INDENT();
487 PRINT("<invalid>\n");
488 return;
489 }
490 } else if (format == kPrintUtilUnannotated) {
491 if (0 != PrintBuf((ConstOctStr)g1_elem_str, sizeof(*g1_elem_str))) {
492 MAKE_INDENT();
493 PRINT("<invalid>\n");
494 return;
495 }
496 } else {
497 MAKE_INDENT();
498 PRINT("<invalid>\n");
499 return;
500 }
501 }
502
PrintG2ElemStr(G2ElemStr const * g2_elem_str,char const * var_name,PrintUtilFormat format)503 void PrintG2ElemStr(G2ElemStr const* g2_elem_str, char const* var_name,
504 PrintUtilFormat format) {
505 if (!var_name) {
506 var_name = "<no name>";
507 }
508 PRINT("%s (G2ElemStr):\n", var_name);
509 if (!g2_elem_str) {
510 MAKE_INDENT();
511 PRINT("<null>\n");
512 return;
513 }
514 if (format == kPrintUtilAnnotated) {
515 MAKE_INDENT();
516 PRINT("x0:\n");
517 if (0 !=
518 PrintBuf((ConstOctStr)&g2_elem_str->x[0], sizeof(g2_elem_str->x[0]))) {
519 MAKE_INDENT();
520 PRINT("<invalid>\n");
521 return;
522 }
523 MAKE_INDENT();
524 PRINT("x1:\n");
525 if (0 !=
526 PrintBuf((ConstOctStr)&g2_elem_str->x[1], sizeof(g2_elem_str->x[1]))) {
527 MAKE_INDENT();
528 PRINT("<invalid>\n");
529 return;
530 }
531 MAKE_INDENT();
532 PRINT("y0:\n");
533 if (0 !=
534 PrintBuf((ConstOctStr)&g2_elem_str->y[0], sizeof(g2_elem_str->y[0]))) {
535 MAKE_INDENT();
536 PRINT("<invalid>\n");
537 return;
538 }
539 MAKE_INDENT();
540 PRINT("y1:\n");
541 if (0 !=
542 PrintBuf((ConstOctStr)&g2_elem_str->y[1], sizeof(g2_elem_str->y[1]))) {
543 MAKE_INDENT();
544 PRINT("<invalid>\n");
545 return;
546 }
547 } else if (format == kPrintUtilUnannotated) {
548 if (0 != PrintBuf((ConstOctStr)g2_elem_str, sizeof(*g2_elem_str))) {
549 MAKE_INDENT();
550 PRINT("<invalid>\n");
551 return;
552 }
553 } else {
554 MAKE_INDENT();
555 PRINT("<invalid>\n");
556 return;
557 }
558 }
559
PrintGtElemStr(GtElemStr const * gt_elem_str,char const * var_name,PrintUtilFormat format)560 void PrintGtElemStr(GtElemStr const* gt_elem_str, char const* var_name,
561 PrintUtilFormat format) {
562 if (!var_name) {
563 var_name = "<no name>";
564 }
565 PRINT("%s (GtElemStr):\n", var_name);
566 if (!gt_elem_str) {
567 MAKE_INDENT();
568 PRINT("<null>\n");
569 return;
570 }
571 if (format == kPrintUtilAnnotated) {
572 unsigned int i = 0;
573 for (i = 0; i < sizeof(gt_elem_str->x) / sizeof(gt_elem_str->x[0]); i++) {
574 MAKE_INDENT();
575 PRINT("x%u:\n", i);
576 if (0 != PrintBuf((ConstOctStr)>_elem_str->x[i],
577 sizeof(gt_elem_str->x[i]))) {
578 MAKE_INDENT();
579 PRINT("<invalid>\n");
580 return;
581 }
582 }
583 } else if (format == kPrintUtilUnannotated) {
584 if (0 != PrintBuf((ConstOctStr)gt_elem_str, sizeof(*gt_elem_str))) {
585 MAKE_INDENT();
586 PRINT("<invalid>\n");
587 return;
588 }
589 } else {
590 MAKE_INDENT();
591 PRINT("<invalid>\n");
592 return;
593 }
594 }
595
596 #ifdef EPID_ENABLE_DEBUG_PRINT
597 #undef EPID_ENABLE_DEBUG_PRINT
598 #endif
599