1/* $NetBSD: example_evp_cipher.c,v 1.4 2023/06/19 21:41:43 christos Exp $ */ 2 3/* 4 * Copyright (c) 2008 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include <config.h> 37#include <krb5/roken.h> 38 39#include <krb5/krb5-types.h> /* should really be stdint.h */ 40#include <hcrypto/evp.h> 41#include <hcrypto/evp-pkcs11.h> 42#ifdef __APPLE__ 43#include <hcrypto/evp-cc.h> 44#endif 45#ifdef _WIN32 46#include <hcrypto/evp-w32.h> 47#endif 48 49#include <err.h> 50#include <assert.h> 51 52/* key and initial vector */ 53static char key[16] = 54 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4" 55 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4"; 56static char ivec[16] = 57 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4" 58 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4"; 59 60static void 61usage(int exit_code) __attribute__((noreturn)); 62 63static void 64usage(int exit_code) 65{ 66 printf("usage: %s in out [pkcs11 | cc | w32]\n", getprogname()); 67 exit(exit_code); 68} 69 70 71int 72main(int argc, char **argv) 73{ 74 int encryptp = 1; 75 const char *ifn = NULL, *ofn = NULL; 76 FILE *in, *out; 77 void *ibuf, *obuf; 78 int ilen, olen; 79 size_t block_size = 0; 80 const EVP_CIPHER *c = EVP_aes_128_cbc(); 81 EVP_CIPHER_CTX ctx; 82 int ret; 83 84 setprogname(argv[0]); 85 86 if (argc == 2) { 87 if (strcmp(argv[1], "--version") == 0) { 88 printf("version"); 89 exit(0); 90 } 91 if (strcmp(argv[1], "--help") == 0) 92 usage(0); 93 usage(1); 94 } else if (argc == 4 || argc == 5) { 95 block_size = atoi(argv[1]); 96 if (block_size == 0) 97 errx(1, "invalid blocksize %s", argv[1]); 98 ifn = argv[2]; 99 ofn = argv[3]; 100 if (argc == 5) { 101 if (strcmp(argv[4], "pkcs11") == 0) 102 c = hc_EVP_pkcs11_aes_128_cbc(); 103#ifdef __APPLE__ 104 else if (strcmp(argv[4], "cc") == 0) 105 c = hc_EVP_cc_aes_128_cbc(); 106#endif 107#ifdef _WIN32 108 else if (strcmp(argv[4], "w32") == 0) 109 c = hc_EVP_w32crypto_aes_128_cbc(); 110#endif 111 else 112 usage(1); 113 } 114 } else 115 usage(1); 116 117 in = fopen(ifn, "r"); 118 if (in == NULL) 119 errx(1, "failed to open input file"); 120 out = fopen(ofn, "w+"); 121 if (out == NULL) 122 errx(1, "failed to open output file"); 123 124 /* Check that key and ivec are long enough */ 125 assert(EVP_CIPHER_key_length(c) <= sizeof(key)); 126 assert(EVP_CIPHER_iv_length(c) <= sizeof(ivec)); 127 128 /* 129 * Allocate buffer, the output buffer is at least 130 * EVP_CIPHER_block_size() longer 131 */ 132 ibuf = malloc(block_size); 133 obuf = malloc(block_size + EVP_CIPHER_block_size(c)); 134 135 /* 136 * Init the memory used for EVP_CIPHER_CTX and set the key and 137 * ivec. 138 */ 139 EVP_CIPHER_CTX_init(&ctx); 140 if (!EVP_CipherInit_ex(&ctx, c, NULL, key, ivec, encryptp)) 141 errx(1, "EVP_CipherInit_ex failed"); 142 143 /* read in buffer */ 144 while ((ilen = fread(ibuf, 1, block_size, in)) > 0) { 145 /* encrypto/decrypt */ 146 ret = EVP_CipherUpdate(&ctx, obuf, &olen, ibuf, ilen); 147 if (ret != 1) { 148 EVP_CIPHER_CTX_cleanup(&ctx); 149 errx(1, "EVP_CipherUpdate failed"); 150 } 151 /* write out to output file */ 152 fwrite(obuf, 1, olen, out); 153 } 154 /* done reading */ 155 fclose(in); 156 157 /* clear up any last bytes left in the output buffer */ 158 ret = EVP_CipherFinal_ex(&ctx, obuf, &olen); 159 EVP_CIPHER_CTX_cleanup(&ctx); 160 if (ret != 1) 161 errx(1, "EVP_CipherFinal_ex failed"); 162 163 /* write the last bytes out and close */ 164 fwrite(obuf, 1, olen, out); 165 fclose(out); 166 167 return 0; 168} 169