Return to gcrypt_crypter.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / gcrypt |
1.1 misho 1: /* 2: * Copyright (C) 2009 Martin Willi 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 "gcrypt_crypter.h" 17: 18: #include <gcrypt.h> 19: 20: #include <utils/debug.h> 21: 22: typedef struct private_gcrypt_crypter_t private_gcrypt_crypter_t; 23: 24: /** 25: * Private data of gcrypt_crypter_t 26: */ 27: struct private_gcrypt_crypter_t { 28: 29: /** 30: * Public part of this class. 31: */ 32: gcrypt_crypter_t public; 33: 34: /** 35: * gcrypt cipher handle 36: */ 37: gcry_cipher_hd_t h; 38: 39: /** 40: * gcrypt algorithm identifier 41: */ 42: int alg; 43: 44: /** 45: * are we using counter mode? 46: */ 47: bool ctr_mode; 48: 49: /** 50: * counter state 51: */ 52: struct { 53: char nonce[4]; 54: char iv[8]; 55: uint32_t counter; 56: } __attribute__((packed)) ctr; 57: }; 58: 59: /** 60: * Set the IV for en/decryption 61: */ 62: static bool set_iv(private_gcrypt_crypter_t *this, chunk_t iv) 63: { 64: if (this->ctr_mode) 65: { 66: memcpy(this->ctr.iv, iv.ptr, sizeof(this->ctr.iv)); 67: this->ctr.counter = htonl(1); 68: return gcry_cipher_setctr(this->h, &this->ctr, sizeof(this->ctr)) == 0; 69: } 70: return gcry_cipher_setiv(this->h, iv.ptr, iv.len) == 0; 71: } 72: 73: METHOD(crypter_t, decrypt, bool, 74: private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) 75: { 76: if (!set_iv(this, iv)) 77: { 78: return FALSE; 79: } 80: if (dst) 81: { 82: *dst = chunk_alloc(data.len); 83: return gcry_cipher_decrypt(this->h, dst->ptr, dst->len, 84: data.ptr, data.len) == 0; 85: } 86: return gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0) == 0; 87: } 88: 89: METHOD(crypter_t, encrypt, bool, 90: private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) 91: { 92: if (!set_iv(this, iv)) 93: { 94: return FALSE; 95: } 96: if (dst) 97: { 98: *dst = chunk_alloc(data.len); 99: return gcry_cipher_encrypt(this->h, dst->ptr, dst->len, 100: data.ptr, data.len) == 0; 101: } 102: return gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0) == 0; 103: } 104: 105: METHOD(crypter_t, get_block_size, size_t, 106: private_gcrypt_crypter_t *this) 107: { 108: size_t len = 0; 109: 110: if (this->ctr_mode) 111: { /* counter mode does not need any padding */ 112: return 1; 113: } 114: gcry_cipher_algo_info(this->alg, GCRYCTL_GET_BLKLEN, NULL, &len); 115: return len; 116: } 117: 118: METHOD(crypter_t, get_iv_size, size_t, 119: private_gcrypt_crypter_t *this) 120: { 121: size_t len = 0; 122: 123: if (this->ctr_mode) 124: { 125: return sizeof(this->ctr.iv); 126: } 127: gcry_cipher_algo_info(this->alg, GCRYCTL_GET_BLKLEN, NULL, &len); 128: return len; 129: } 130: 131: METHOD(crypter_t, get_key_size, size_t, 132: private_gcrypt_crypter_t *this) 133: { 134: size_t len = 0; 135: 136: gcry_cipher_algo_info(this->alg, GCRYCTL_GET_KEYLEN, NULL, &len); 137: if (this->ctr_mode) 138: { 139: return len + sizeof(this->ctr.nonce); 140: } 141: return len; 142: } 143: 144: METHOD(crypter_t, set_key, bool, 145: private_gcrypt_crypter_t *this, chunk_t key) 146: { 147: if (this->ctr_mode) 148: { 149: /* last 4 bytes are the nonce */ 150: memcpy(this->ctr.nonce, key.ptr + key.len - sizeof(this->ctr.nonce), 151: sizeof(this->ctr.nonce)); 152: key.len -= sizeof(this->ctr.nonce); 153: } 154: return gcry_cipher_setkey(this->h, key.ptr, key.len) == 0; 155: } 156: 157: METHOD(crypter_t, destroy, void, 158: private_gcrypt_crypter_t *this) 159: { 160: gcry_cipher_close(this->h); 161: free(this); 162: } 163: 164: /* 165: * Described in header 166: */ 167: gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo, 168: size_t key_size) 169: { 170: private_gcrypt_crypter_t *this; 171: int gcrypt_alg; 172: int mode = GCRY_CIPHER_MODE_CBC; 173: gcry_error_t err; 174: 175: switch (algo) 176: { 177: case ENCR_DES: 178: gcrypt_alg = GCRY_CIPHER_DES; 179: break; 180: case ENCR_DES_ECB: 181: gcrypt_alg = GCRY_CIPHER_DES; 182: mode = GCRY_CIPHER_MODE_ECB; 183: break; 184: case ENCR_3DES: 185: gcrypt_alg = GCRY_CIPHER_3DES; 186: break; 187: case ENCR_IDEA: 188: /* currently not implemented in gcrypt */ 189: return NULL; 190: case ENCR_CAST: 191: gcrypt_alg = GCRY_CIPHER_CAST5; 192: break; 193: case ENCR_BLOWFISH: 194: if (key_size != 16 && key_size != 0) 195: { /* gcrypt currently supports 128 bit blowfish only */ 196: return NULL; 197: } 198: gcrypt_alg = GCRY_CIPHER_BLOWFISH; 199: break; 200: case ENCR_AES_CTR: 201: case ENCR_AES_ECB: 202: mode = (algo == ENCR_AES_CTR) ? GCRY_CIPHER_MODE_CTR : 203: GCRY_CIPHER_MODE_ECB; 204: /* fall */ 205: case ENCR_AES_CBC: 206: switch (key_size) 207: { 208: case 0: 209: case 16: 210: gcrypt_alg = GCRY_CIPHER_AES128; 211: break; 212: case 24: 213: gcrypt_alg = GCRY_CIPHER_AES192; 214: break; 215: case 32: 216: gcrypt_alg = GCRY_CIPHER_AES256; 217: break; 218: default: 219: return NULL; 220: } 221: break; 222: case ENCR_CAMELLIA_CTR: 223: mode = GCRY_CIPHER_MODE_CTR; 224: /* fall */ 225: case ENCR_CAMELLIA_CBC: 226: switch (key_size) 227: { 228: #ifdef HAVE_GCRY_CIPHER_CAMELLIA 229: case 0: 230: case 16: 231: gcrypt_alg = GCRY_CIPHER_CAMELLIA128; 232: break; 233: case 24: 234: gcrypt_alg = GCRY_CIPHER_CAMELLIA192; 235: break; 236: case 32: 237: gcrypt_alg = GCRY_CIPHER_CAMELLIA256; 238: break; 239: #endif /* HAVE_GCRY_CIPHER_CAMELLIA */ 240: default: 241: return NULL; 242: } 243: break; 244: case ENCR_SERPENT_CBC: 245: switch (key_size) 246: { 247: case 0: 248: case 16: 249: gcrypt_alg = GCRY_CIPHER_SERPENT128; 250: break; 251: case 24: 252: gcrypt_alg = GCRY_CIPHER_SERPENT192; 253: break; 254: case 32: 255: gcrypt_alg = GCRY_CIPHER_SERPENT256; 256: break; 257: default: 258: return NULL; 259: } 260: break; 261: case ENCR_TWOFISH_CBC: 262: switch (key_size) 263: { 264: case 0: 265: case 16: 266: gcrypt_alg = GCRY_CIPHER_TWOFISH128; 267: break; 268: case 32: 269: gcrypt_alg = GCRY_CIPHER_TWOFISH; 270: break; 271: default: 272: return NULL; 273: } 274: break; 275: default: 276: return NULL; 277: } 278: 279: INIT(this, 280: .public = { 281: .crypter = { 282: .encrypt = _encrypt, 283: .decrypt = _decrypt, 284: .get_block_size = _get_block_size, 285: .get_iv_size = _get_iv_size, 286: .get_key_size = _get_key_size, 287: .set_key = _set_key, 288: .destroy = _destroy, 289: }, 290: }, 291: .alg = gcrypt_alg, 292: .ctr_mode = mode == GCRY_CIPHER_MODE_CTR, 293: ); 294: 295: err = gcry_cipher_open(&this->h, gcrypt_alg, mode, 0); 296: if (err) 297: { 298: DBG1(DBG_LIB, "grcy_cipher_open(%N) failed: %s", 299: encryption_algorithm_names, algo, gpg_strerror(err)); 300: free(this); 301: return NULL; 302: } 303: return &this->public; 304: } 305: