1/* 2 * Copyright (c) 2008 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 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 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34/* Windows crypto provider plugin, sample */ 35 36#include <config.h> 37 38#define HC_DEPRECATED 39 40#include <sys/types.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <assert.h> 45 46#include <evp.h> 47 48#include <crypt.h> 49 50 51static HCRYPTPROV hCryptProv = NULL; 52 53/* 54 * 55 */ 56 57struct generic_key { 58 HCRYPTKEY *hKey; 59}; 60 61static int 62generic_cbc_do_cipher(EVP_CIPHER_CTX *ctx, 63 unsigned char *out, 64 const unsigned char *in, 65 unsigned int size) 66{ 67 struct generic_key *gk = ctx->cipher_data; 68 BOOL bResult; 69 DWORD length = size; 70 71 bResult = CryptSetKeyParam(gk->hKey, KP_IV, ctx->iv, 0); 72 _ASSERT(bResult); 73 74 memcpy(out, in, size); 75 76 if (ctx->encrypt) 77 bResult = CryptEncrypt(gk->hKey, 0, TRUE, 0, out, &length, size); 78 else 79 bResult = CryptDecrypt(gk->hKey, 0, TRUE, 0, out, &length); 80 _ASSERT(bResult); 81 82 return 1; 83} 84 85static int 86generic_cleanup(EVP_CIPHER_CTX *ctx) 87{ 88 struct generic_key *gk = ctx->cipher_data; 89 CryptDestroyKey(gk->hKey); 90 gk->hKey = NULL; 91 return 1; 92} 93 94static HCRYPTKEY 95import_key(int alg, const unsigned char *key, size_t keylen) 96{ 97 struct { 98 BLOBHEADER hdr; 99 DWORD len; 100 BYTE key[1]; 101 } *key_blob; 102 size_t bloblen = sizeof(*key_blob) - 1 + keylen; 103 104 key_blob = malloc(bloblen); 105 106 key_blob->hdr.bType = PLAINTEXTKEYBLOB; 107 key_blob->hdr.bVersion = CUR_BLOB_VERSION; 108 key_blob->hdr.reserved = 0; 109 key_blob->hdr.aiKeyAlg = alg; 110 key_blob->len = 24; 111 memcpy(key_blob->key, key, keylen); 112 113 bResult = CryptImportKey(hCryptProv, 114 (void *)key_blob, bloblen, 0, 0, 115 &gk->hKey); 116 free(key_blob); 117 _ASSERT(bResult); 118 119 return hKey; 120} 121 122static int 123crypto_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, 124 const unsigned char * key, 125 const unsigned char * iv, 126 int encp) 127{ 128 struct generic_key *gk = ctx->cipher_data; 129 DWORD paramData; 130 131 gk->hKey = import_key(CALG_3DES, 132 key->key->keyvalue.data, 133 key->key->keyvalue.len); 134 135 return 1; 136} 137 138/** 139 * The tripple DES cipher type (Micrsoft crypt provider) 140 * 141 * @return the DES-EDE3-CBC EVP_CIPHER pointer. 142 * 143 * @ingroup hcrypto_evp 144 */ 145 146const EVP_CIPHER * 147EVP_wincrypt_des_ede3_cbc(void) 148{ 149 static const EVP_CIPHER des_ede3_cbc = { 150 0, 151 8, 152 24, 153 8, 154 EVP_CIPH_CBC_MODE, 155 crypto_des_ede3_cbc_init, 156 generic_cbc_do_cipher, 157 generic_cleanup, 158 sizeof(struct generic_key), 159 NULL, 160 NULL, 161 NULL, 162 NULL 163 }; 164 return &des_ede3_cbc; 165} 166 167/* 168 * 169 */ 170 171struct generic_hash { 172 HCRYPTHASH hHash; 173}; 174 175static void 176crypto_md5_init(struct generic_hash *m); 177{ 178 BOOL bResult; 179 bResult = CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &m->hHash); 180 _ASSERT(bResult); 181} 182 183static void 184generic_hash_update (struct generic_hash *m, const void *p, size_t len) 185{ 186 BOOL bResult; 187 bResult = CryptHashData(m->hHash, data, ( DWORD )len, 0 ); 188 _ASSERT(bResult); 189} 190 191static void 192generic_hash_final (void *res, struct generic_hash *m); 193{ 194 DWORD length; 195 BOOL bResult; 196 bResult = CryptGetHashParam(m->hHash, HP_HASHVAL, res, &length, 0) 197 _ASSERT(bResult); 198} 199 200static void 201generic_hash_cleanup(struct generic_hash *m) 202{ 203 CryptDestroyHash(m->hHash); 204 m->hHash = NULL; 205} 206 207const EVP_MD * 208EVP_wincrypt_md5(void) 209{ 210 static const struct hc_evp_md md5 = { 211 16, 212 64, 213 sizeof(struct generic_hash), 214 (hc_evp_md_init)crypto_md5_init, 215 (hc_evp_md_update)generic_hash_update, 216 (hc_evp_md_final)generic_hash_final, 217 (hc_evp_md_cleanup)generic_hash_cleanup 218 }; 219 return &md5; 220} 221