|
@@ -29,9 +29,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
29
|
29
|
#undef NDEBUG
|
30
|
30
|
|
31
|
31
|
#include <stdint.h>
|
|
32
|
+#include <stdlib.h>
|
32
|
33
|
#include <string.h>
|
33
|
34
|
#include <assert.h>
|
34
|
35
|
#include <ipxe/crypto.h>
|
|
36
|
+#include <ipxe/profile.h>
|
35
|
37
|
#include "cbc_test.h"
|
36
|
38
|
|
37
|
39
|
/**
|
|
@@ -49,8 +51,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
49
|
51
|
int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
|
50
|
52
|
size_t key_len, const void *iv, const void *plaintext,
|
51
|
53
|
const void *expected_ciphertext, size_t len ) {
|
52
|
|
- uint8_t ctx[ cipher->ctxsize ];
|
53
|
|
- uint8_t ciphertext[ len ];
|
|
54
|
+ uint8_t ctx[cipher->ctxsize];
|
|
55
|
+ uint8_t ciphertext[len];
|
54
|
56
|
int rc;
|
55
|
57
|
|
56
|
58
|
/* Initialise cipher */
|
|
@@ -80,8 +82,8 @@ int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
|
80
|
82
|
int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
|
81
|
83
|
size_t key_len, const void *iv, const void *ciphertext,
|
82
|
84
|
const void *expected_plaintext, size_t len ) {
|
83
|
|
- uint8_t ctx[ cipher->ctxsize ];
|
84
|
|
- uint8_t plaintext[ len ];
|
|
85
|
+ uint8_t ctx[cipher->ctxsize];
|
|
86
|
+ uint8_t plaintext[len];
|
85
|
87
|
int rc;
|
86
|
88
|
|
87
|
89
|
/* Initialise cipher */
|
|
@@ -95,3 +97,75 @@ int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
|
95
|
97
|
/* Verify result */
|
96
|
98
|
return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
|
97
|
99
|
}
|
|
100
|
+
|
|
101
|
+/**
|
|
102
|
+ * Calculate CBC encryption or decryption cost
|
|
103
|
+ *
|
|
104
|
+ * @v cipher Cipher algorithm
|
|
105
|
+ * @v key_len Length of key
|
|
106
|
+ * @v op Encryption or decryption operation
|
|
107
|
+ * @ret cost Cost (in cycles per byte)
|
|
108
|
+ */
|
|
109
|
+static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
|
|
110
|
+ size_t key_len,
|
|
111
|
+ void ( * op ) ( struct cipher_algorithm *cipher,
|
|
112
|
+ void *ctx, const void *src,
|
|
113
|
+ void *dst, size_t len ) ) {
|
|
114
|
+ static uint8_t random[8192]; /* Too large for stack */
|
|
115
|
+ uint8_t key[key_len];
|
|
116
|
+ uint8_t iv[cipher->blocksize];
|
|
117
|
+ uint8_t ctx[cipher->ctxsize];
|
|
118
|
+ union profiler profiler;
|
|
119
|
+ unsigned long long elapsed;
|
|
120
|
+ unsigned long cost;
|
|
121
|
+ unsigned int i;
|
|
122
|
+ int rc;
|
|
123
|
+
|
|
124
|
+ /* Fill buffer with pseudo-random data */
|
|
125
|
+ srand ( 0x1234568 );
|
|
126
|
+ for ( i = 0 ; i < sizeof ( random ) ; i++ )
|
|
127
|
+ random[i] = rand();
|
|
128
|
+ for ( i = 0 ; i < sizeof ( key ) ; i++ )
|
|
129
|
+ key[i] = rand();
|
|
130
|
+ for ( i = 0 ; i < sizeof ( iv ) ; i++ )
|
|
131
|
+ iv[i] = rand();
|
|
132
|
+
|
|
133
|
+ /* Initialise cipher */
|
|
134
|
+ rc = cipher_setkey ( cipher, ctx, key, key_len );
|
|
135
|
+ assert ( rc == 0 );
|
|
136
|
+ cipher_setiv ( cipher, ctx, iv );
|
|
137
|
+
|
|
138
|
+ /* Time operation */
|
|
139
|
+ profile ( &profiler );
|
|
140
|
+ op ( cipher, ctx, random, random, sizeof ( random ) );
|
|
141
|
+ elapsed = profile ( &profiler );
|
|
142
|
+
|
|
143
|
+ /* Round to nearest whole number of cycles per byte */
|
|
144
|
+ cost = ( ( elapsed + ( sizeof ( random ) / 2 ) ) / sizeof ( random ) );
|
|
145
|
+
|
|
146
|
+ return cost;
|
|
147
|
+}
|
|
148
|
+
|
|
149
|
+/**
|
|
150
|
+ * Calculate CBC encryption cost
|
|
151
|
+ *
|
|
152
|
+ * @v cipher Cipher algorithm
|
|
153
|
+ * @v key_len Length of key
|
|
154
|
+ * @ret cost Cost (in cycles per byte)
|
|
155
|
+ */
|
|
156
|
+unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
|
|
157
|
+ size_t key_len ) {
|
|
158
|
+ return cbc_cost ( cipher, key_len, cipher_encrypt );
|
|
159
|
+}
|
|
160
|
+
|
|
161
|
+/**
|
|
162
|
+ * Calculate CBC decryption cost
|
|
163
|
+ *
|
|
164
|
+ * @v cipher Cipher algorithm
|
|
165
|
+ * @v key_len Length of key
|
|
166
|
+ * @ret cost Cost (in cycles per byte)
|
|
167
|
+ */
|
|
168
|
+unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
|
|
169
|
+ size_t key_len ) {
|
|
170
|
+ return cbc_cost ( cipher, key_len, cipher_decrypt );
|
|
171
|
+}
|