]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bcal/bcal-performance.c
086e597195060a17976e84f2301f8c3d9a659c65
[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.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 {
60     bcdesc_t bc;
61     memcpy_P(&bc, bcd, sizeof(bcdesc_t));
62     uint8_t ctx[bc.ctxsize_B];
63     uint8_t data[(bc.blocksize_b + 7) / 8];
64     uint16_t keysize = get_keysize(bc.valid_keysize_desc);
65     uint8_t key[(keysize + 7) / 8];
66     uint64_t t;
67     uint8_t i;
68
69     if (bc.type != BCDESC_TYPE_BLOCKCIPHER)
70         return;
71     calibrateTimer();
72     print_overhead();
73     printf_P(PSTR("\n\n === %S performance === \n"
74             "\ttype:             blockcipher\n"
75             "\tkeysize (bits):     %5"PRIu16"\n"
76             "\tctxsize (bytes):    %5"PRIu16"\n"
77             "\tblocksize (bits):   %5"PRIu16"\n"),
78             bc.name, keysize, bc.ctxsize_B, bc.blocksize_b);
79     uart0_flush();
80     t = 0;
81     if (bc.init.init1) {
82         if ((bc.flags & BC_INIT_TYPE) == BC_INIT_TYPE_1) {
83             for (i = 0; i < 32; ++i) {
84                 startTimer(1);
85                 START_TIMER;
86                 (bc.init.init1)(key, &ctx);
87                 STOP_TIMER;
88                 t += stopTimer();
89                 if (i != 31 && bc.free) {
90                     bc.free(&ctx);
91                 }
92             }
93         } else {
94             for (i = 0; i < 32; ++i) {
95                 startTimer(1);
96                 START_TIMER;
97                 (bc.init.init2)(key, keysize, &ctx);
98                 STOP_TIMER;
99                 t += stopTimer();
100                 if (i != 31 && bc.free) {
101                     bc.free(&ctx);
102                 }
103             }
104         }
105         t >>= 5;
106         printf_P(PSTR("    init (cycles):      %5"PRIu16"\n"), t);
107     }
108
109     uart0_flush();
110     t = 0;
111     for (i = 0; i < 32; ++i) {
112         startTimer(0);
113         START_TIMER;
114         bc.enc.enc1(data, &ctx);
115         STOP_TIMER;
116         t += stopTimer();
117     }
118     t >>= 5;
119     printf_P(PSTR("    encrypt (cycles):   %5"PRIu16"\n"), t);
120
121     uart0_flush();
122     t = 0;
123     for (i = 0; i < 32; ++i) {
124         startTimer(0);
125         START_TIMER;
126         bc.dec.dec1(data, &ctx);
127         STOP_TIMER;
128         t += stopTimer();
129     }
130     t >>= 5;
131     printf_P(PSTR("    decrypt (cycles):   %5"PRIu16"\n"), t);
132     uart0_flush();
133
134     if (bc.free) {
135         uart0_flush();
136         bc.free(&ctx);
137     }
138 }
139
140 void bcal_stacksize(const bcdesc_t *bcd)
141 {
142     bcdesc_t bc;
143     stack_measuring_ctx_t smctx;
144     memcpy_P(&bc, bcd, sizeof(bcdesc_t));
145     uint8_t ctx[bc.ctxsize_B];
146     uint8_t data[(bc.blocksize_b + 7) / 8];
147     uint16_t keysize = get_keysize(bc.valid_keysize_desc);
148     uint8_t key[(keysize + 7) / 8];
149     uint16_t t1 = 0, t2 = 0;
150
151     if (bc.type != BCDESC_TYPE_BLOCKCIPHER)
152         return;
153     printf_P(PSTR("\n === %S stack-usage ===\n"), bc.name);
154
155     uart0_flush();
156
157     if (bc.init.init1) {
158         if ((bc.flags & BC_INIT_TYPE) == BC_INIT_TYPE_1) {
159             cli();
160             stack_measure_init(&smctx, PATTERN_A);
161             bc.init.init1(&ctx, key);
162             t1 = stack_measure_final(&smctx);
163             stack_measure_init(&smctx, PATTERN_B);
164             bc.init.init1(&ctx, key);
165             t2 = stack_measure_final(&smctx);
166             sei();
167         } else {
168             cli();
169             stack_measure_init(&smctx, PATTERN_A);
170             bc.init.init2(&ctx, keysize, key);
171             t1 = stack_measure_final(&smctx);
172             stack_measure_init(&smctx, PATTERN_B);
173             bc.init.init2(&ctx, keysize, key);
174             t2 = stack_measure_final(&smctx);
175             sei();
176         }
177
178         t1 = (t1 > t2) ? t1 : t2;
179         printf_P(PSTR("    init (bytes):       %5"PRIu16"\n"), t1);
180     }
181     cli();
182     stack_measure_init(&smctx, PATTERN_A);
183     bc.enc.enc1(data, &ctx);
184     t1 = stack_measure_final(&smctx);
185     stack_measure_init(&smctx, PATTERN_B);
186     bc.enc.enc1(data, &ctx);
187     t2 = stack_measure_final(&smctx);
188     sei();
189
190     t1 = (t1 > t2) ? t1 : t2;
191     printf_P(PSTR("    encBlock (bytes):   %5"PRIu16"\n"), t1);
192
193     cli();
194     stack_measure_init(&smctx, PATTERN_A);
195     bc.dec.dec1(data, &ctx);
196     t1 = stack_measure_final(&smctx);
197     stack_measure_init(&smctx, PATTERN_B);
198     bc.dec.dec1(data, &ctx);
199     t2 = stack_measure_final(&smctx);
200     sei();
201
202     t1 = (t1 > t2) ? t1 : t2;
203     printf_P(PSTR("    decBlock (bytes):   %5"PRIu16"\n"), t1);
204
205     if (bc.free) {
206         bc.free(&ctx);
207     }
208 }
209
210 void bcal_performance_multiple(const bcdesc_t * const *bcd_list)
211 {
212     const bcdesc_t *bcd;
213     for (;;) {
214         bcd = (void*) pgm_read_word(bcd_list);
215         if (!bcd) {
216             puts_P(PSTR("\n End of performance figures\n"));
217             return;
218         }
219         bcal_performance(bcd);
220         bcal_stacksize(bcd);
221         bcd_list = (void*) ((uint8_t*) bcd_list + 2);
222     }
223 }