Return to openssl_crypter.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / openssl |
1.1 misho 1: /* 2: * Copyright (C) 2008 Tobias Brunner 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "openssl_crypter.h" 17: 18: #include <openssl/evp.h> 19: 20: typedef struct private_openssl_crypter_t private_openssl_crypter_t; 21: 22: /** 23: * Private data of openssl_crypter_t 24: */ 25: struct private_openssl_crypter_t { 26: 27: /** 28: * Public part of this class. 29: */ 30: openssl_crypter_t public; 31: 32: /* 33: * the key 34: */ 35: chunk_t key; 36: 37: /* 38: * the cipher to use 39: */ 40: const EVP_CIPHER *cipher; 41: }; 42: 43: /** 44: * Look up an OpenSSL algorithm name and validate its key size 45: */ 46: static char* lookup_algorithm(uint16_t ikev2_algo, size_t *key_size) 47: { 48: struct { 49: /* identifier specified in IKEv2 */ 50: int ikev2_id; 51: /* name of the algorithm, as used in OpenSSL */ 52: char *name; 53: /* default key size in bytes */ 54: size_t key_def; 55: /* minimum key size */ 56: size_t key_min; 57: /* maximum key size */ 58: size_t key_max; 59: } mappings[] = { 60: {ENCR_DES, "des-cbc", 8, 8, 8}, 61: {ENCR_3DES, "des-ede3-cbc", 24, 24, 24}, 62: {ENCR_RC5, "rc5-cbc", 16, 5, 255}, 63: {ENCR_IDEA, "idea-cbc", 16, 16, 16}, 64: {ENCR_CAST, "cast5-cbc", 16, 5, 16}, 65: {ENCR_BLOWFISH, "bf-cbc", 16, 5, 56}, 66: }; 67: int i; 68: 69: for (i = 0; i < countof(mappings); i++) 70: { 71: if (ikev2_algo == mappings[i].ikev2_id) 72: { 73: /* set the key size if it is not set */ 74: if (*key_size == 0) 75: { 76: *key_size = mappings[i].key_def; 77: } 78: /* validate key size */ 79: if (*key_size < mappings[i].key_min || 80: *key_size > mappings[i].key_max) 81: { 82: return NULL; 83: } 84: return mappings[i].name; 85: } 86: } 87: return NULL; 88: } 89: 90: /** 91: * Do the actual en/decryption in an EVP context 92: */ 93: static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, 94: chunk_t *dst, int enc) 95: { 96: EVP_CIPHER_CTX *ctx; 97: int len; 98: u_char *out; 99: bool success = FALSE; 100: 101: out = data.ptr; 102: if (dst) 103: { 104: *dst = chunk_alloc(data.len); 105: out = dst->ptr; 106: } 107: ctx = EVP_CIPHER_CTX_new(); 108: if (EVP_CipherInit_ex(ctx, this->cipher, NULL, NULL, NULL, enc) && 109: EVP_CIPHER_CTX_set_padding(ctx, 0) /* disable padding */ && 110: EVP_CIPHER_CTX_set_key_length(ctx, this->key.len) && 111: EVP_CipherInit_ex(ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) && 112: EVP_CipherUpdate(ctx, out, &len, data.ptr, data.len) && 113: /* since padding is disabled this does nothing */ 114: EVP_CipherFinal_ex(ctx, out + len, &len)) 115: { 116: success = TRUE; 117: } 118: EVP_CIPHER_CTX_free(ctx); 119: return success; 120: } 121: 122: METHOD(crypter_t, decrypt, bool, 123: private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) 124: { 125: return crypt(this, data, iv, dst, 0); 126: } 127: 128: METHOD(crypter_t, encrypt, bool, 129: private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) 130: { 131: return crypt(this, data, iv, dst, 1); 132: } 133: 134: METHOD(crypter_t, get_block_size, size_t, 135: private_openssl_crypter_t *this) 136: { 137: return EVP_CIPHER_block_size(this->cipher); 138: } 139: 140: METHOD(crypter_t, get_iv_size, size_t, 141: private_openssl_crypter_t *this) 142: { 143: return EVP_CIPHER_iv_length(this->cipher); 144: } 145: 146: METHOD(crypter_t, get_key_size, size_t, 147: private_openssl_crypter_t *this) 148: { 149: return this->key.len; 150: } 151: 152: METHOD(crypter_t, set_key, bool, 153: private_openssl_crypter_t *this, chunk_t key) 154: { 155: memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len)); 156: return TRUE; 157: } 158: 159: METHOD(crypter_t, destroy, void, 160: private_openssl_crypter_t *this) 161: { 162: chunk_clear(&this->key); 163: free(this); 164: } 165: 166: /* 167: * Described in header 168: */ 169: openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo, 170: size_t key_size) 171: { 172: private_openssl_crypter_t *this; 173: 174: INIT(this, 175: .public = { 176: .crypter = { 177: .encrypt = _encrypt, 178: .decrypt = _decrypt, 179: .get_block_size = _get_block_size, 180: .get_iv_size = _get_iv_size, 181: .get_key_size = _get_key_size, 182: .set_key = _set_key, 183: .destroy = _destroy, 184: }, 185: }, 186: ); 187: 188: switch (algo) 189: { 190: case ENCR_NULL: 191: this->cipher = EVP_enc_null(); 192: key_size = 0; 193: break; 194: case ENCR_AES_CBC: 195: switch (key_size) 196: { 197: case 0: 198: key_size = 16; 199: /* FALL */ 200: case 16: /* AES 128 */ 201: this->cipher = EVP_get_cipherbyname("aes-128-cbc"); 202: break; 203: case 24: /* AES-192 */ 204: this->cipher = EVP_get_cipherbyname("aes-192-cbc"); 205: break; 206: case 32: /* AES-256 */ 207: this->cipher = EVP_get_cipherbyname("aes-256-cbc"); 208: break; 209: default: 210: free(this); 211: return NULL; 212: } 213: break; 214: case ENCR_AES_ECB: 215: switch (key_size) 216: { 217: case 0: 218: key_size = 16; 219: /* FALL */ 220: case 16: /* AES 128 */ 221: this->cipher = EVP_get_cipherbyname("aes-128-ecb"); 222: break; 223: case 24: /* AES-192 */ 224: this->cipher = EVP_get_cipherbyname("aes-192-ecb"); 225: break; 226: case 32: /* AES-256 */ 227: this->cipher = EVP_get_cipherbyname("aes-256-ecb"); 228: break; 229: default: 230: free(this); 231: return NULL; 232: } 233: break; 234: case ENCR_CAMELLIA_CBC: 235: switch (key_size) 236: { 237: case 0: 238: key_size = 16; 239: /* FALL */ 240: case 16: /* CAMELLIA 128 */ 241: this->cipher = EVP_get_cipherbyname("camellia-128-cbc"); 242: break; 243: case 24: /* CAMELLIA 192 */ 244: this->cipher = EVP_get_cipherbyname("camellia-192-cbc"); 245: break; 246: case 32: /* CAMELLIA 256 */ 247: this->cipher = EVP_get_cipherbyname("camellia-256-cbc"); 248: break; 249: default: 250: free(this); 251: return NULL; 252: } 253: break; 254: #ifndef OPENSSL_NO_DES 255: case ENCR_DES_ECB: 256: key_size = 8; 257: this->cipher = EVP_des_ecb(); 258: break; 259: #endif 260: default: 261: { 262: char* name; 263: 264: name = lookup_algorithm(algo, &key_size); 265: if (!name) 266: { 267: /* algo unavailable or key_size invalid */ 268: free(this); 269: return NULL; 270: } 271: this->cipher = EVP_get_cipherbyname(name); 272: break; 273: } 274: } 275: 276: if (!this->cipher) 277: { 278: /* OpenSSL does not support the requested algo */ 279: free(this); 280: return NULL; 281: } 282: 283: this->key = chunk_alloc(key_size); 284: 285: return &this->public; 286: }