~ubuntu-branches/ubuntu/raring/ipxe/raring

« back to all changes in this revision

Viewing changes to src/tests/cbc_test.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-11-14 15:47:31 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20121114154731-jhuy5d1h2jw75qe9
Tags: 1.0.0+git-4.d6b0b76-0ubuntu1
* New upstream snapshot:
  - d/p/iscsi*.patch: Dropped - included in snapshot.
  - Refreshed all other patches.
* d/p/enable-https.patch: Enable HTTPS support (LP: #1025239).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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
 
17
 * 02110-1301, USA.
 
18
 */
 
19
 
 
20
FILE_LICENCE ( GPL2_OR_LATER );
 
21
 
 
22
/** @file
 
23
 *
 
24
 * CBC self-tests
 
25
 *
 
26
 */
 
27
 
 
28
/* Forcibly enable assertions */
 
29
#undef NDEBUG
 
30
 
 
31
#include <stdint.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
#include <assert.h>
 
35
#include <ipxe/crypto.h>
 
36
#include <ipxe/profile.h>
 
37
#include "cbc_test.h"
 
38
 
 
39
/**
 
40
 * Test CBC encryption
 
41
 *
 
42
 * @v cipher                    Cipher algorithm
 
43
 * @v key                       Key
 
44
 * @v key_len                   Length of key
 
45
 * @v iv                        Initialisation vector
 
46
 * @v plaintext                 Plaintext data
 
47
 * @v expected_ciphertext       Expected ciphertext data
 
48
 * @v len                       Length of data
 
49
 * @ret ok                      Ciphertext is as expected
 
50
 */
 
51
int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
 
52
                       size_t key_len, const void *iv, const void *plaintext,
 
53
                       const void *expected_ciphertext, size_t len ) {
 
54
        uint8_t ctx[cipher->ctxsize];
 
55
        uint8_t ciphertext[len];
 
56
        int rc;
 
57
 
 
58
        /* Initialise cipher */
 
59
        rc = cipher_setkey ( cipher, ctx, key, key_len );
 
60
        assert ( rc == 0 );
 
61
        cipher_setiv ( cipher, ctx, iv );
 
62
 
 
63
        /* Perform encryption */
 
64
        cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
 
65
 
 
66
        /* Verify result */
 
67
        return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
 
68
}
 
69
 
 
70
/**
 
71
 * Test CBC decryption
 
72
 *
 
73
 * @v cipher                    Cipher algorithm
 
74
 * @v key                       Key
 
75
 * @v key_len                   Length of key
 
76
 * @v iv                        Initialisation vector
 
77
 * @v ciphertext                Ciphertext data
 
78
 * @v expected_plaintext        Expected plaintext data
 
79
 * @v len                       Length of data
 
80
 * @ret ok                      Plaintext is as expected
 
81
 */
 
82
int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
 
83
                       size_t key_len, const void *iv, const void *ciphertext,
 
84
                       const void *expected_plaintext, size_t len ) {
 
85
        uint8_t ctx[cipher->ctxsize];
 
86
        uint8_t plaintext[len];
 
87
        int rc;
 
88
 
 
89
        /* Initialise cipher */
 
90
        rc = cipher_setkey ( cipher, ctx, key, key_len );
 
91
        assert ( rc == 0 );
 
92
        cipher_setiv ( cipher, ctx, iv );
 
93
 
 
94
        /* Perform encryption */
 
95
        cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
 
96
 
 
97
        /* Verify result */
 
98
        return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
 
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
}