ia64/xen-unstable

view tools/vtpm_manager/crypto/sym_crypto.c @ 8977:f84d5cdd9895

Clean up segment selector fixup and validation.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Feb 23 14:43:45 2006 +0100 (2006-02-23)
parents 06d84bf87159
children 5014fd2b5c5a
line source
1 // ===================================================================
2 //
3 // Copyright (c) 2005, Intel Corp.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 // * Neither the name of Intel Corporation nor the names of its
17 // contributors may be used to endorse or promote products derived
18 // from this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32 // ===================================================================
33 //
34 // sym_crypto.c
35 //
36 // Symmetric crypto portion of crypto
37 //
38 // ==================================================================
40 #include <openssl/evp.h>
41 #include <openssl/rand.h>
43 #include "tcg.h"
44 #include "sym_crypto.h"
46 typedef enum crypt_op_type_t {
47 CRYPT_ENCRYPT,
48 CRYPT_DECRYPT
49 } crypt_op_type_t;
51 TPM_RESULT ossl_symcrypto_op (symkey_t* key,
52 const buffer_t* in,
53 const buffer_t* iv,
54 buffer_t * out,
55 crypt_op_type_t optype);
58 // this is initialized in Crypto_Init()
59 const EVP_CIPHER * SYM_CIPHER = NULL;
61 const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] = {0};
64 TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) {
65 TPM_RESULT status = TPM_SUCCESS;
67 EVP_CIPHER_CTX_init (&key->context);
69 key->cipher = SYM_CIPHER;
71 status = buffer_init_copy (&key->key, keybits);
72 STATUSCHECK(status);
74 goto egress;
76 abort_egress:
77 EVP_CIPHER_CTX_cleanup (&key->context);
79 egress:
81 return status;
82 }
86 TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
87 int res;
88 TPM_RESULT status = TPM_SUCCESS;
90 // hmm, EVP_CIPHER_CTX_init does not return a value
91 EVP_CIPHER_CTX_init (&key->context);
93 key->cipher = SYM_CIPHER;
95 status = buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL);
96 STATUSCHECK (status);
98 // and generate the key material
99 res = RAND_pseudo_bytes (key->key.bytes, key->key.size);
100 if (res < 0)
101 ERRORDIE (TPM_SHORTRANDOM);
104 goto egress;
106 abort_egress:
107 EVP_CIPHER_CTX_cleanup (&key->context);
108 buffer_free (&key->key);
110 egress:
111 return status;
112 }
115 TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
116 const buffer_t* clear,
117 buffer_t* o_cipher) {
118 TPM_RESULT status = TPM_SUCCESS;
120 buffer_t iv, cipher_alias;
122 buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV);
124 buffer_init (o_cipher,
125 clear->size +
126 EVP_CIPHER_iv_length(key->cipher) +
127 EVP_CIPHER_block_size (key->cipher),
128 0);
130 // copy the IV into the front
131 buffer_copy (o_cipher, &iv);
133 // make an alias into which we'll put the ciphertext
134 buffer_init_alias (&cipher_alias, o_cipher, EVP_CIPHER_iv_length(key->cipher), 0);
136 status = ossl_symcrypto_op (key, clear, &iv, &cipher_alias, CRYPT_ENCRYPT);
137 STATUSCHECK (status);
139 // set the output size correctly
140 o_cipher->size += cipher_alias.size;
142 goto egress;
144 abort_egress:
146 egress:
148 return status;
150 }
154 TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
155 const buffer_t* cipher,
156 buffer_t* o_clear) {
157 TPM_RESULT status = TPM_SUCCESS;
159 buffer_t iv, cipher_alias;
161 // alias for the IV
162 buffer_init_alias (&iv, cipher, 0, EVP_CIPHER_iv_length(key->cipher));
164 // make an alias to where the ciphertext is, after the IV
165 buffer_init_alias (&cipher_alias, cipher, EVP_CIPHER_iv_length(key->cipher), 0);
167 // prepare the output buffer
168 status = buffer_init (o_clear,
169 cipher->size
170 - EVP_CIPHER_iv_length(key->cipher)
171 + EVP_CIPHER_block_size(key->cipher),
172 0);
173 STATUSCHECK(status);
175 // and decrypt
176 status = ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT);
177 STATUSCHECK (status);
179 goto egress;
181 abort_egress:
182 buffer_free (o_clear);
184 egress:
186 return status;
187 }
191 TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) {
192 buffer_memset (&key->key, 0);
193 buffer_free (&key->key);
195 EVP_CIPHER_CTX_cleanup (&key->context);
197 return TPM_SUCCESS;
198 }
201 TPM_RESULT ossl_symcrypto_op (symkey_t* key,
202 const buffer_t* in,
203 const buffer_t* iv,
204 buffer_t * out,
205 crypt_op_type_t optype) {
206 TPM_RESULT status = TPM_SUCCESS;
208 int inlen, outlen;
209 tpm_size_t running;
211 if ( ! EVP_CipherInit_ex (&key->context,
212 key->cipher, NULL, key->key.bytes, iv->bytes,
213 optype == CRYPT_ENCRYPT ? 1 : 0) )
214 ERRORDIE (TPM_FAIL);
218 inlen = in->size;
220 outlen = 0;
221 running = 0;
224 if ( ! EVP_CipherUpdate (&key->context, out->bytes, &outlen, in->bytes, inlen) )
225 ERRORDIE (TPM_FAIL);
227 running += outlen;
229 if ( ! EVP_CipherFinal_ex (&key->context, out->bytes + running, &outlen) )
230 ERRORDIE (TPM_FAIL);
232 running += outlen;
234 out->size = running;
236 goto egress;
238 abort_egress:
239 egress:
241 return status;
242 }