1 /* $NetBSD: example_evp_cipher.c,v 1.1.1.1 2011/04/13 18:14:49 elric 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 <krb5/krb5-types.h> /* should really be stdint.h */ 37 #include <hcrypto/evp.h> 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <err.h> 43 #include <assert.h> 44 45 #include <krb5/roken.h> 46 47 /* key and initial vector */ 48 static char key[16] = 49 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4" 50 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4"; 51 static char ivec[16] = 52 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4" 53 "\xaa\xbb\x45\xd4\xaa\xbb\x45\xd4"; 54 55 static void 56 usage(int exit_code) __attribute__((noreturn)); 57 58 static void 59 usage(int exit_code) 60 { 61 printf("usage: %s in out\n", getprogname()); 62 exit(exit_code); 63 } 64 65 66 int 67 main(int argc, char **argv) 68 { 69 int encryptp = 1; 70 const char *ifn = NULL, *ofn = NULL; 71 FILE *in, *out; 72 void *ibuf, *obuf; 73 int ilen, olen; 74 size_t block_size = 0; 75 const EVP_CIPHER *c = EVP_aes_128_cbc(); 76 EVP_CIPHER_CTX ctx; 77 int ret; 78 79 setprogname(argv[0]); 80 81 if (argc == 2) { 82 if (strcmp(argv[1], "--version") == 0) { 83 printf("version"); 84 exit(0); 85 } 86 if (strcmp(argv[1], "--help") == 0) 87 usage(0); 88 usage(1); 89 } else if (argc == 4) { 90 block_size = atoi(argv[1]); 91 if (block_size == 0) 92 errx(1, "invalid blocksize %s", argv[1]); 93 ifn = argv[2]; 94 ofn = argv[3]; 95 } else 96 usage(1); 97 98 in = fopen(ifn, "r"); 99 if (in == NULL) 100 errx(1, "failed to open input file"); 101 out = fopen(ofn, "w+"); 102 if (out == NULL) 103 errx(1, "failed to open output file"); 104 105 /* Check that key and ivec are long enough */ 106 assert(EVP_CIPHER_key_length(c) <= sizeof(key)); 107 assert(EVP_CIPHER_iv_length(c) <= sizeof(ivec)); 108 109 /* 110 * Allocate buffer, the output buffer is at least 111 * EVP_CIPHER_block_size() longer 112 */ 113 ibuf = malloc(block_size); 114 obuf = malloc(block_size + EVP_CIPHER_block_size(c)); 115 116 /* 117 * Init the memory used for EVP_CIPHER_CTX and set the key and 118 * ivec. 119 */ 120 EVP_CIPHER_CTX_init(&ctx); 121 EVP_CipherInit_ex(&ctx, c, NULL, key, ivec, encryptp); 122 123 /* read in buffer */ 124 while ((ilen = fread(ibuf, 1, block_size, in)) > 0) { 125 /* encrypto/decrypt */ 126 ret = EVP_CipherUpdate(&ctx, obuf, &olen, ibuf, ilen); 127 if (ret != 1) { 128 EVP_CIPHER_CTX_cleanup(&ctx); 129 errx(1, "EVP_CipherUpdate failed"); 130 } 131 /* write out to output file */ 132 fwrite(obuf, 1, olen, out); 133 } 134 /* done reading */ 135 fclose(in); 136 137 /* clear up any last bytes left in the output buffer */ 138 ret = EVP_CipherFinal_ex(&ctx, obuf, &olen); 139 EVP_CIPHER_CTX_cleanup(&ctx); 140 if (ret != 1) 141 errx(1, "EVP_CipherFinal_ex failed"); 142 143 /* write the last bytes out and close */ 144 fwrite(obuf, 1, olen, out); 145 fclose(out); 146 147 return 0; 148 } 149