1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/evp/openbsd_hw.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,446 @@
1.4 +/* Written by Ben Laurie, 2001 */
1.5 +/*
1.6 + * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
1.7 + *
1.8 + * Redistribution and use in source and binary forms, with or without
1.9 + * modification, are permitted provided that the following conditions
1.10 + * are met:
1.11 + *
1.12 + * 1. Redistributions of source code must retain the above copyright
1.13 + * notice, this list of conditions and the following disclaimer.
1.14 + *
1.15 + * 2. Redistributions in binary form must reproduce the above copyright
1.16 + * notice, this list of conditions and the following disclaimer in
1.17 + * the documentation and/or other materials provided with the
1.18 + * distribution.
1.19 + *
1.20 + * 3. All advertising materials mentioning features or use of this
1.21 + * software must display the following acknowledgment:
1.22 + * "This product includes software developed by the OpenSSL Project
1.23 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.24 + *
1.25 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.26 + * endorse or promote products derived from this software without
1.27 + * prior written permission. For written permission, please contact
1.28 + * openssl-core@openssl.org.
1.29 + *
1.30 + * 5. Products derived from this software may not be called "OpenSSL"
1.31 + * nor may "OpenSSL" appear in their names without prior written
1.32 + * permission of the OpenSSL Project.
1.33 + *
1.34 + * 6. Redistributions of any form whatsoever must retain the following
1.35 + * acknowledgment:
1.36 + * "This product includes software developed by the OpenSSL Project
1.37 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.38 + *
1.39 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.40 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.41 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.42 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.43 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.44 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.45 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.46 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.47 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.48 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.49 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.50 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.51 + */
1.52 +
1.53 +#include <openssl/evp.h>
1.54 +#include <openssl/objects.h>
1.55 +#include <openssl/rsa.h>
1.56 +#include "evp_locl.h"
1.57 +
1.58 +/* This stuff should now all be supported through
1.59 + * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up */
1.60 +static void *dummy=&dummy;
1.61 +
1.62 +#if 0
1.63 +
1.64 +/* check flag after OpenSSL headers to ensure make depend works */
1.65 +#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
1.66 +
1.67 +#include <fcntl.h>
1.68 +#include <stdio.h>
1.69 +#include <errno.h>
1.70 +#include <sys/ioctl.h>
1.71 +#include <crypto/cryptodev.h>
1.72 +#include <unistd.h>
1.73 +#include <assert.h>
1.74 +
1.75 +/* longest key supported in hardware */
1.76 +#define MAX_HW_KEY 24
1.77 +#define MAX_HW_IV 8
1.78 +
1.79 +#define MD5_DIGEST_LENGTH 16
1.80 +#define MD5_CBLOCK 64
1.81 +
1.82 +static int fd;
1.83 +static int dev_failed;
1.84 +
1.85 +typedef struct session_op session_op;
1.86 +
1.87 +#define CDATA(ctx) EVP_C_DATA(session_op,ctx)
1.88 +
1.89 +static void err(const char *str)
1.90 + {
1.91 + fprintf(stderr,"%s: errno %d\n",str,errno);
1.92 + }
1.93 +
1.94 +static int dev_crypto_init(session_op *ses)
1.95 + {
1.96 + if(dev_failed)
1.97 + return 0;
1.98 + if(!fd)
1.99 + {
1.100 + int cryptodev_fd;
1.101 +
1.102 + if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0)
1.103 + {
1.104 + err("/dev/crypto");
1.105 + dev_failed=1;
1.106 + return 0;
1.107 + }
1.108 + if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
1.109 + {
1.110 + err("CRIOGET failed");
1.111 + close(cryptodev_fd);
1.112 + dev_failed=1;
1.113 + return 0;
1.114 + }
1.115 + close(cryptodev_fd);
1.116 + }
1.117 + assert(ses);
1.118 + memset(ses,'\0',sizeof *ses);
1.119 +
1.120 + return 1;
1.121 + }
1.122 +
1.123 +static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
1.124 + {
1.125 + if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
1.126 + err("CIOCFSESSION failed");
1.127 +
1.128 + OPENSSL_free(CDATA(ctx)->key);
1.129 +
1.130 + return 1;
1.131 + }
1.132 +
1.133 +static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
1.134 + const unsigned char *key,int klen)
1.135 + {
1.136 + if(!dev_crypto_init(CDATA(ctx)))
1.137 + return 0;
1.138 +
1.139 + CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
1.140 +
1.141 + assert(ctx->cipher->iv_len <= MAX_HW_IV);
1.142 +
1.143 + memcpy(CDATA(ctx)->key,key,klen);
1.144 +
1.145 + CDATA(ctx)->cipher=cipher;
1.146 + CDATA(ctx)->keylen=klen;
1.147 +
1.148 + if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
1.149 + {
1.150 + err("CIOCGSESSION failed");
1.151 + return 0;
1.152 + }
1.153 + return 1;
1.154 + }
1.155 +
1.156 +static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
1.157 + const unsigned char *in,unsigned int inl)
1.158 + {
1.159 + struct crypt_op cryp;
1.160 + unsigned char lb[MAX_HW_IV];
1.161 +
1.162 + if(!inl)
1.163 + return 1;
1.164 +
1.165 + assert(CDATA(ctx));
1.166 + assert(!dev_failed);
1.167 +
1.168 + memset(&cryp,'\0',sizeof cryp);
1.169 + cryp.ses=CDATA(ctx)->ses;
1.170 + cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
1.171 + cryp.flags=0;
1.172 + cryp.len=inl;
1.173 + assert((inl&(ctx->cipher->block_size-1)) == 0);
1.174 + cryp.src=(caddr_t)in;
1.175 + cryp.dst=(caddr_t)out;
1.176 + cryp.mac=0;
1.177 + if(ctx->cipher->iv_len)
1.178 + cryp.iv=(caddr_t)ctx->iv;
1.179 +
1.180 + if(!ctx->encrypt)
1.181 + memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
1.182 +
1.183 + if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
1.184 + {
1.185 + if(errno == EINVAL) /* buffers are misaligned */
1.186 + {
1.187 + unsigned int cinl=0;
1.188 + char *cin=NULL;
1.189 + char *cout=NULL;
1.190 +
1.191 + /* NB: this can only make cinl != inl with stream ciphers */
1.192 + cinl=(inl+3)/4*4;
1.193 +
1.194 + if(((unsigned long)in&3) || cinl != inl)
1.195 + {
1.196 + cin=OPENSSL_malloc(cinl);
1.197 + memcpy(cin,in,inl);
1.198 + cryp.src=cin;
1.199 + }
1.200 +
1.201 + if(((unsigned long)out&3) || cinl != inl)
1.202 + {
1.203 + cout=OPENSSL_malloc(cinl);
1.204 + cryp.dst=cout;
1.205 + }
1.206 +
1.207 + cryp.len=cinl;
1.208 +
1.209 + if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
1.210 + {
1.211 + err("CIOCCRYPT(2) failed");
1.212 + printf("src=%p dst=%p\n",cryp.src,cryp.dst);
1.213 + abort();
1.214 + return 0;
1.215 + }
1.216 +
1.217 + if(cout)
1.218 + {
1.219 + memcpy(out,cout,inl);
1.220 + OPENSSL_free(cout);
1.221 + }
1.222 + if(cin)
1.223 + OPENSSL_free(cin);
1.224 + }
1.225 + else
1.226 + {
1.227 + err("CIOCCRYPT failed");
1.228 + abort();
1.229 + return 0;
1.230 + }
1.231 + }
1.232 +
1.233 + if(ctx->encrypt)
1.234 + memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
1.235 + else
1.236 + memcpy(ctx->iv,lb,ctx->cipher->iv_len);
1.237 +
1.238 + return 1;
1.239 + }
1.240 +
1.241 +static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
1.242 + const unsigned char *key,
1.243 + const unsigned char *iv, int enc)
1.244 + { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }
1.245 +
1.246 +#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher
1.247 +
1.248 +BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
1.249 + 0, dev_crypto_des_ede3_init_key,
1.250 + dev_crypto_cleanup,
1.251 + EVP_CIPHER_set_asn1_iv,
1.252 + EVP_CIPHER_get_asn1_iv,
1.253 + NULL)
1.254 +
1.255 +static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
1.256 + const unsigned char *key,
1.257 + const unsigned char *iv, int enc)
1.258 + { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }
1.259 +
1.260 +static const EVP_CIPHER r4_cipher=
1.261 + {
1.262 + NID_rc4,
1.263 + 1,16,0, /* FIXME: key should be up to 256 bytes */
1.264 + EVP_CIPH_VARIABLE_LENGTH,
1.265 + dev_crypto_rc4_init_key,
1.266 + dev_crypto_cipher,
1.267 + dev_crypto_cleanup,
1.268 + sizeof(session_op),
1.269 + NULL,
1.270 + NULL,
1.271 + NULL
1.272 + };
1.273 +
1.274 +const EVP_CIPHER *EVP_dev_crypto_rc4(void)
1.275 + { return &r4_cipher; }
1.276 +
1.277 +typedef struct
1.278 + {
1.279 + session_op sess;
1.280 + char *data;
1.281 + int len;
1.282 + unsigned char md[EVP_MAX_MD_SIZE];
1.283 + } MD_DATA;
1.284 +
1.285 +static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
1.286 + {
1.287 + if(!dev_crypto_init(&md_data->sess))
1.288 + return 0;
1.289 +
1.290 + md_data->len=0;
1.291 + md_data->data=NULL;
1.292 +
1.293 + md_data->sess.mac=mac;
1.294 +
1.295 + if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
1.296 + {
1.297 + err("CIOCGSESSION failed");
1.298 + return 0;
1.299 + }
1.300 + return 1;
1.301 + }
1.302 +
1.303 +static int dev_crypto_cleanup_digest(MD_DATA *md_data)
1.304 + {
1.305 + if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1)
1.306 + {
1.307 + err("CIOCFSESSION failed");
1.308 + return 0;
1.309 + }
1.310 +
1.311 + return 1;
1.312 + }
1.313 +
1.314 +/* FIXME: if device can do chained MACs, then don't accumulate */
1.315 +/* FIXME: move accumulation to the framework */
1.316 +static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
1.317 + { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
1.318 +
1.319 +static int do_digest(int ses,unsigned char *md,const void *data,int len)
1.320 + {
1.321 + struct crypt_op cryp;
1.322 + static unsigned char md5zero[16]=
1.323 + {
1.324 + 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
1.325 + 0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
1.326 + };
1.327 +
1.328 + /* some cards can't do zero length */
1.329 + if(!len)
1.330 + {
1.331 + memcpy(md,md5zero,16);
1.332 + return 1;
1.333 + }
1.334 +
1.335 + memset(&cryp,'\0',sizeof cryp);
1.336 + cryp.ses=ses;
1.337 + cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
1.338 + cryp.len=len;
1.339 + cryp.src=(caddr_t)data;
1.340 + cryp.dst=(caddr_t)data; // FIXME!!!
1.341 + cryp.mac=(caddr_t)md;
1.342 +
1.343 + if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
1.344 + {
1.345 + if(errno == EINVAL) /* buffer is misaligned */
1.346 + {
1.347 + char *dcopy;
1.348 +
1.349 + dcopy=OPENSSL_malloc(len);
1.350 + memcpy(dcopy,data,len);
1.351 + cryp.src=dcopy;
1.352 + cryp.dst=cryp.src; // FIXME!!!
1.353 +
1.354 + if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
1.355 + {
1.356 + err("CIOCCRYPT(MAC2) failed");
1.357 + abort();
1.358 + return 0;
1.359 + }
1.360 + OPENSSL_free(dcopy);
1.361 + }
1.362 + else
1.363 + {
1.364 + err("CIOCCRYPT(MAC) failed");
1.365 + abort();
1.366 + return 0;
1.367 + }
1.368 + }
1.369 + // printf("done\n");
1.370 +
1.371 + return 1;
1.372 + }
1.373 +
1.374 +static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
1.375 + unsigned long len)
1.376 + {
1.377 + MD_DATA *md_data=ctx->md_data;
1.378 +
1.379 + if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
1.380 + return do_digest(md_data->sess.ses,md_data->md,data,len);
1.381 +
1.382 + md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
1.383 + memcpy(md_data->data+md_data->len,data,len);
1.384 + md_data->len+=len;
1.385 +
1.386 + return 1;
1.387 + }
1.388 +
1.389 +static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
1.390 + {
1.391 + int ret;
1.392 + MD_DATA *md_data=ctx->md_data;
1.393 +
1.394 + if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
1.395 + {
1.396 + memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
1.397 + ret=1;
1.398 + }
1.399 + else
1.400 + {
1.401 + ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
1.402 + OPENSSL_free(md_data->data);
1.403 + md_data->data=NULL;
1.404 + md_data->len=0;
1.405 + }
1.406 +
1.407 + return ret;
1.408 + }
1.409 +
1.410 +static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
1.411 + {
1.412 + const MD_DATA *from_md=from->md_data;
1.413 + MD_DATA *to_md=to->md_data;
1.414 +
1.415 + // How do we copy sessions?
1.416 + assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
1.417 +
1.418 + to_md->data=OPENSSL_malloc(from_md->len);
1.419 + memcpy(to_md->data,from_md->data,from_md->len);
1.420 +
1.421 + return 1;
1.422 + }
1.423 +
1.424 +static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx)
1.425 + {
1.426 + return dev_crypto_cleanup_digest(ctx->md_data);
1.427 + }
1.428 +
1.429 +static const EVP_MD md5_md=
1.430 + {
1.431 + NID_md5,
1.432 + NID_md5WithRSAEncryption,
1.433 + MD5_DIGEST_LENGTH,
1.434 + EVP_MD_FLAG_ONESHOT, // XXX: set according to device info...
1.435 + dev_crypto_md5_init,
1.436 + dev_crypto_md5_update,
1.437 + dev_crypto_md5_final,
1.438 + dev_crypto_md5_copy,
1.439 + dev_crypto_md5_cleanup,
1.440 + EVP_PKEY_RSA_method,
1.441 + MD5_CBLOCK,
1.442 + sizeof(MD_DATA),
1.443 + };
1.444 +
1.445 +const EVP_MD *EVP_dev_crypto_md5(void)
1.446 + { return &md5_md; }
1.447 +
1.448 +#endif
1.449 +#endif