]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bcal/bcal-performance.c
some minor improvments and bug fixes
[avr-crypto-lib.git] / bcal / bcal-performance.c
1 /* bcal-performance.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21  * \file    bcal-performance.c
22  * \author  Daniel Otte
23  * \email   daniel.otte@rub.de
24  * \date    2010-02-16
25  * \license GPLv3 or later
26  *
27  */
28
29 #include "bcal-performance.h"
30 #include "keysize_descriptor.h"
31 #include "blockcipher_descriptor.h"
32 #include "performance_test.h"
33 #include "stack_measuring.h"
34 #include "cli.h"
35 #include "uart_i.h"
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdio.h>
40 #include <avr/pgmspace.h>
41
42 #define PATTERN_A 0xAA
43 #define PATTERN_B 0x55
44
45 /*
46 static
47 void printvalue(unsigned long v){
48         char str[20];
49         int i;
50         ultoa(v, str, 10);
51         for(i=0; i<10-strlen(str); ++i){
52                 cli_putc(' ');
53         }
54         cli_putstr(str);
55 }
56 */
57
58 void bcal_performance(const bcdesc_t* bcd){
59         bcdesc_t bc;
60         memcpy_P(&bc, bcd, sizeof(bcdesc_t));
61         uint8_t ctx[bc.ctxsize_B];
62         uint8_t data[(bc.blocksize_b+7)/8];
63         uint16_t keysize = get_keysize(bc.valid_keysize_desc);
64         uint8_t key[(keysize+7)/8];
65         uint64_t t;
66         uint8_t i;
67
68         if(bc.type != BCDESC_TYPE_BLOCKCIPHER)
69                 return;
70         calibrateTimer();
71         print_overhead();
72         printf_P(PSTR("\n\n === %S"), bc.name);
73         printf_P(PSTR(" performance === \n"
74                       "    type:             blockcipher\n"
75                       "    keysize (bits):     %5"PRIu16"\n"), keysize);
76         printf_P(PSTR("    ctxsize (bytes):    %5"PRIu16"\n"), bc.ctxsize_B);
77         printf_P(PSTR("    blocksize (bits):   %5"PRIu16"\n"), bc.blocksize_b);
78         uart0_flush();
79         t=0;
80         if(bc.init.init1){
81                 if((bc.flags & BC_INIT_TYPE) == BC_INIT_TYPE_1){
82                         for(i=0; i<32; ++i){
83                                 startTimer(1);
84                                 START_TIMER;
85                                 (bc.init.init1)(key, &ctx);
86                                 STOP_TIMER;
87                                 t += stopTimer();
88                                 if(i!=31 && bc.free){
89                                         bc.free(&ctx);
90                                 }
91                         }
92                 } else {
93                         for(i=0; i<32; ++i){
94                                 startTimer(1);
95                                 START_TIMER;
96                                 (bc.init.init2)(key, keysize, &ctx);
97                                 STOP_TIMER;
98                                 t += stopTimer();
99                                 if(i!=31 && bc.free){
100                                         bc.free(&ctx);
101                                 }
102                         }
103                 }
104                 t>>=5;
105                 printf_P(PSTR("    init (cycles):      %5"PRIu16"\n"), t);
106         }
107
108     uart0_flush();
109         t=0;
110         for(i=0; i<32; ++i){
111                 startTimer(0);
112                 START_TIMER;
113                 bc.enc.enc1(data, &ctx);
114                 STOP_TIMER;
115                 t += stopTimer();
116         }
117         t>>=5;
118         printf_P(PSTR("    encrypt (cycles):   %5"PRIu16"\n"), t);
119
120     uart0_flush();
121         t=0;
122         for(i=0; i<32; ++i){
123                 startTimer(0);
124                 START_TIMER;
125                 bc.dec.dec1(data, &ctx);
126                 STOP_TIMER;
127                 t += stopTimer();
128         }
129         t>>=5;
130         printf_P(PSTR("    decrypt (cycles):   %5"PRIu16"\n"), t);
131     uart0_flush();
132
133         if(bc.free){
134             uart0_flush();
135                 bc.free(&ctx);
136         }
137 }
138
139 void bcal_stacksize(const bcdesc_t* bcd){
140         bcdesc_t bc;
141         stack_measuring_ctx_t smctx;
142         memcpy_P(&bc, bcd, sizeof(bcdesc_t));
143         uint8_t ctx[bc.ctxsize_B];
144         uint8_t data[(bc.blocksize_b+7)/8];
145         uint16_t keysize = get_keysize(bc.valid_keysize_desc);
146         uint8_t key[(keysize+7)/8];
147         uint16_t t1 = 0, t2 = 0;
148
149         if(bc.type != BCDESC_TYPE_BLOCKCIPHER)
150                 return;
151         printf_P(PSTR("\n === %S stack-usage ===\n"),bc.name);
152
153         uart0_flush();
154
155         if(bc.init.init1){
156                 if((bc.flags & BC_INIT_TYPE) == BC_INIT_TYPE_1){
157                 cli();
158                         stack_measure_init(&smctx, PATTERN_A);
159                         bc.init.init1(&ctx, key);
160                         t1 = stack_measure_final(&smctx);
161                         stack_measure_init(&smctx, PATTERN_B);
162                         bc.init.init1(&ctx, key);
163                         t2 = stack_measure_final(&smctx);
164                         sei();
165                 } else {
166                 cli();
167                         stack_measure_init(&smctx, PATTERN_A);
168                         bc.init.init2(&ctx, keysize, key);
169                         t1 = stack_measure_final(&smctx);
170                         stack_measure_init(&smctx, PATTERN_B);
171                         bc.init.init2(&ctx, keysize, key);
172             t2 = stack_measure_final(&smctx);
173             sei();
174         }
175
176                 t1 = (t1>t2)?t1:t2;
177                 printf_P(PSTR("    init (bytes):       %5"PRIu16"\n"), t1);
178         }
179         cli();
180         stack_measure_init(&smctx, PATTERN_A);
181         bc.enc.enc1(data, &ctx);
182         t1 = stack_measure_final(&smctx);
183         stack_measure_init(&smctx, PATTERN_B);
184         bc.enc.enc1(data, &ctx);
185         t2 = stack_measure_final(&smctx);
186         sei();
187
188         t1 = (t1>t2)?t1:t2;
189         printf_P(PSTR("    encBlock (bytes):   %5"PRIu16"\n"), t1);
190
191         cli();
192         stack_measure_init(&smctx, PATTERN_A);
193         bc.dec.dec1(data, &ctx);
194         t1 = stack_measure_final(&smctx);
195         stack_measure_init(&smctx, PATTERN_B);
196         bc.dec.dec1(data, &ctx);
197         t2 = stack_measure_final(&smctx);
198         sei();
199
200         t1 = (t1>t2)?t1:t2;
201         printf_P(PSTR("    decBlock (bytes):   %5"PRIu16"\n"), t1);
202
203         if(bc.free){
204                 bc.free(&ctx);
205         }
206 }
207
208 void bcal_performance_multiple(const bcdesc_t* const* bcd_list){
209         const bcdesc_t* bcd;
210         for(;;){
211                 bcd = (void*)pgm_read_word(bcd_list);
212                 if(!bcd){
213                         puts_P(PSTR("\n End of performance figures\n"));
214                         return;
215                 }
216                 bcal_performance(bcd);
217                 bcal_stacksize(bcd);
218                 bcd_list = (void*)((uint8_t*)bcd_list + 2);
219         }
220 }