2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 FILE_LICENCE ( GPL2_OR_LATER );
28 /* Forcibly enable assertions */
35 #include <ipxe/crypto.h>
36 #include <ipxe/profile.h>
39 /** Number of sample iterations for profiling */
40 #define PROFILE_COUNT 16
45 * @v cipher Cipher algorithm
47 * @v key_len Length of key
48 * @v iv Initialisation vector
49 * @v plaintext Plaintext data
50 * @v expected_ciphertext Expected ciphertext data
51 * @v len Length of data
52 * @ret ok Ciphertext is as expected
54 int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
55 size_t key_len, const void *iv, const void *plaintext,
56 const void *expected_ciphertext, size_t len ) {
57 uint8_t ctx[cipher->ctxsize];
58 uint8_t ciphertext[len];
61 /* Initialise cipher */
62 rc = cipher_setkey ( cipher, ctx, key, key_len );
64 cipher_setiv ( cipher, ctx, iv );
66 /* Perform encryption */
67 cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
70 return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
76 * @v cipher Cipher algorithm
78 * @v key_len Length of key
79 * @v iv Initialisation vector
80 * @v ciphertext Ciphertext data
81 * @v expected_plaintext Expected plaintext data
82 * @v len Length of data
83 * @ret ok Plaintext is as expected
85 int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
86 size_t key_len, const void *iv, const void *ciphertext,
87 const void *expected_plaintext, size_t len ) {
88 uint8_t ctx[cipher->ctxsize];
89 uint8_t plaintext[len];
92 /* Initialise cipher */
93 rc = cipher_setkey ( cipher, ctx, key, key_len );
95 cipher_setiv ( cipher, ctx, iv );
97 /* Perform encryption */
98 cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
101 return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
105 * Calculate CBC encryption or decryption cost
107 * @v cipher Cipher algorithm
108 * @v key_len Length of key
109 * @v op Encryption or decryption operation
110 * @ret cost Cost (in cycles per byte)
112 static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
114 void ( * op ) ( struct cipher_algorithm *cipher,
115 void *ctx, const void *src,
116 void *dst, size_t len ) ) {
117 static uint8_t random[8192]; /* Too large for stack */
118 uint8_t key[key_len];
119 uint8_t iv[cipher->blocksize];
120 uint8_t ctx[cipher->ctxsize];
121 struct profiler profiler;
126 /* Fill buffer with pseudo-random data */
128 for ( i = 0 ; i < sizeof ( random ) ; i++ )
130 for ( i = 0 ; i < sizeof ( key ) ; i++ )
132 for ( i = 0 ; i < sizeof ( iv ) ; i++ )
135 /* Initialise cipher */
136 rc = cipher_setkey ( cipher, ctx, key, key_len );
138 cipher_setiv ( cipher, ctx, iv );
140 /* Profile cipher operation */
141 memset ( &profiler, 0, sizeof ( profiler ) );
142 for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
143 profile_start ( &profiler );
144 op ( cipher, ctx, random, random, sizeof ( random ) );
145 profile_stop ( &profiler );
148 /* Round to nearest whole number of cycles per byte */
149 cost = ( ( profile_mean ( &profiler ) + ( sizeof ( random ) / 2 ) ) /
156 * Calculate CBC encryption cost
158 * @v cipher Cipher algorithm
159 * @v key_len Length of key
160 * @ret cost Cost (in cycles per byte)
162 unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
164 return cbc_cost ( cipher, key_len, cipher_encrypt );
168 * Calculate CBC decryption cost
170 * @v cipher Cipher algorithm
171 * @v key_len Length of key
172 * @ret cost Cost (in cycles per byte)
174 unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
176 return cbc_cost ( cipher, key_len, cipher_decrypt );