Annotation of embedaddon/strongswan/src/libstrongswan/plugins/af_alg/af_alg_crypter.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: *
! 5: * Copyright (C) 2019 Andreas Steffen
! 6: * HSR Hochschule fuer Technik Rapperswil
! 7: *
! 8: * This program is free software; you can redistribute it and/or modify it
! 9: * under the terms of the GNU General Public License as published by the
! 10: * Free Software Foundation; either version 2 of the License, or (at your
! 11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 12: *
! 13: * This program is distributed in the hope that it will be useful, but
! 14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 16: * for more details.
! 17: */
! 18:
! 19: #include "af_alg_crypter.h"
! 20: #include "af_alg_ops.h"
! 21:
! 22: typedef struct private_af_alg_crypter_t private_af_alg_crypter_t;
! 23:
! 24: /**
! 25: * Private data of af_alg_crypter_t
! 26: */
! 27: struct private_af_alg_crypter_t {
! 28:
! 29: /**
! 30: * Public part of this class.
! 31: */
! 32: af_alg_crypter_t public;
! 33:
! 34: /**
! 35: * AF_ALG operations
! 36: */
! 37: af_alg_ops_t *ops;
! 38:
! 39: /**
! 40: * Size of the truncated signature
! 41: */
! 42: size_t block_size;
! 43:
! 44: /**
! 45: * Size of the keymat
! 46: */
! 47: size_t keymat_size;
! 48:
! 49: /**
! 50: * Size of initialization vector
! 51: */
! 52: size_t iv_size;
! 53: };
! 54:
! 55: /**
! 56: * Algorithm database
! 57: */
! 58: static struct {
! 59: encryption_algorithm_t id;
! 60: char *name;
! 61: size_t block_size;
! 62: /* key size of the algorithm */
! 63: size_t key_size;
! 64: /* size of the keying material (key + nonce for ctr mode) */
! 65: size_t keymat_size;
! 66: size_t iv_size;
! 67: } algs[AF_ALG_CRYPTER] = {
! 68: {ENCR_DES, "cbc(des)", 8, 8, 8, 8, },
! 69: {ENCR_DES_ECB, "ecb(des)", 8, 8, 8, 0, },
! 70: {ENCR_3DES, "cbc(des3_ede)", 8, 24, 24, 8, },
! 71: {ENCR_AES_CBC, "cbc(aes)", 16, 16, 16, 16, },
! 72: {ENCR_AES_CBC, "cbc(aes)", 16, 24, 24, 16, },
! 73: {ENCR_AES_CBC, "cbc(aes)", 16, 32, 32, 16, },
! 74: {ENCR_AES_ECB, "ecb(aes)", 16, 16, 16, 0, },
! 75: {ENCR_AES_ECB, "ecb(aes)", 16, 24, 24, 0, },
! 76: {ENCR_AES_ECB, "ecb(aes)", 16, 32, 32, 0, },
! 77: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 16, 20, 8, },
! 78: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 24, 28, 8, },
! 79: {ENCR_AES_CTR, "rfc3686(ctr(aes))", 1, 32, 36, 8, },
! 80: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 16, 16, 16, },
! 81: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 24, 24, 16, },
! 82: {ENCR_CAMELLIA_CBC, "cbc(camellia)", 16, 32, 32, 16, },
! 83: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 16, 20, 8, },
! 84: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 24, 28, 8, },
! 85: {ENCR_CAMELLIA_CTR, "rfc3686(ctr(camellia))", 1, 32, 36, 8, },
! 86: {ENCR_CAST, "cbc(cast5)", 8, 16, 16, 8, },
! 87: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 16, 16, 8, },
! 88: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 24, 24, 8, },
! 89: {ENCR_BLOWFISH, "cbc(blowfish)", 8, 32, 32, 8, },
! 90: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 16, 16, 16, },
! 91: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 24, 24, 16, },
! 92: {ENCR_SERPENT_CBC, "cbc(serpent)", 16, 32, 32, 16, },
! 93: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 16, 16, 16, },
! 94: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 24, 24, 16, },
! 95: {ENCR_TWOFISH_CBC, "cbc(twofish)", 16, 32, 32, 16, },
! 96: };
! 97:
! 98: /**
! 99: * See header.
! 100: */
! 101: void af_alg_crypter_probe(plugin_feature_t *features, int *pos)
! 102: {
! 103: af_alg_ops_t *ops;
! 104: int i;
! 105:
! 106: for (i = 0; i < countof(algs); i++)
! 107: {
! 108: ops = af_alg_ops_create("skcipher", algs[i].name);
! 109: if (ops)
! 110: {
! 111: ops->destroy(ops);
! 112: features[(*pos)++] = PLUGIN_PROVIDE(CRYPTER,
! 113: algs[i].id, algs[i].key_size);
! 114: }
! 115: }
! 116: }
! 117:
! 118: /**
! 119: * Get the kernel algorithm string and block/key size for our identifier
! 120: */
! 121: static size_t lookup_alg(encryption_algorithm_t algo, char **name,
! 122: size_t key_size, size_t *keymat_size, size_t *iv_size)
! 123: {
! 124: int i;
! 125:
! 126: for (i = 0; i < countof(algs); i++)
! 127: {
! 128: if (algs[i].id == algo &&
! 129: (key_size == 0 || algs[i].key_size == key_size))
! 130: {
! 131: *name = algs[i].name;
! 132: *keymat_size = algs[i].keymat_size;
! 133: *iv_size = algs[i].iv_size;
! 134: return algs[i].block_size;
! 135: }
! 136: }
! 137: return 0;
! 138: }
! 139:
! 140: METHOD(crypter_t, decrypt, bool,
! 141: private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
! 142: {
! 143: if (dst)
! 144: {
! 145: *dst = chunk_alloc(data.len);
! 146: return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, dst->ptr);
! 147: }
! 148: return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, data.ptr);
! 149: }
! 150:
! 151: METHOD(crypter_t, encrypt, bool,
! 152: private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
! 153: {
! 154: if (dst)
! 155: {
! 156: *dst = chunk_alloc(data.len);
! 157: return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, dst->ptr);
! 158: }
! 159: return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr);
! 160: }
! 161:
! 162: METHOD(crypter_t, get_block_size, size_t,
! 163: private_af_alg_crypter_t *this)
! 164: {
! 165: return this->block_size;
! 166: }
! 167:
! 168: METHOD(crypter_t, get_iv_size, size_t,
! 169: private_af_alg_crypter_t *this)
! 170: {
! 171: return this->iv_size;
! 172: }
! 173:
! 174: METHOD(crypter_t, get_key_size, size_t,
! 175: private_af_alg_crypter_t *this)
! 176: {
! 177: return this->keymat_size;
! 178: }
! 179:
! 180: METHOD(crypter_t, set_key, bool,
! 181: private_af_alg_crypter_t *this, chunk_t key)
! 182: {
! 183: return this->ops->set_key(this->ops, key);
! 184: }
! 185:
! 186: METHOD(crypter_t, destroy, void,
! 187: private_af_alg_crypter_t *this)
! 188: {
! 189: this->ops->destroy(this->ops);
! 190: free(this);
! 191: }
! 192:
! 193: /*
! 194: * Described in header
! 195: */
! 196: af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo,
! 197: size_t key_size)
! 198: {
! 199: private_af_alg_crypter_t *this;
! 200: size_t block_size, keymat_size, iv_size;
! 201: char *name;
! 202:
! 203: block_size = lookup_alg(algo, &name, key_size, &keymat_size, &iv_size);
! 204: if (!block_size)
! 205: { /* not supported by kernel */
! 206: return NULL;
! 207: }
! 208:
! 209: INIT(this,
! 210: .public = {
! 211: .crypter = {
! 212: .encrypt = _encrypt,
! 213: .decrypt = _decrypt,
! 214: .get_block_size = _get_block_size,
! 215: .get_iv_size = _get_iv_size,
! 216: .get_key_size = _get_key_size,
! 217: .set_key = _set_key,
! 218: .destroy = _destroy,
! 219: },
! 220: },
! 221: .block_size = block_size,
! 222: .keymat_size = keymat_size,
! 223: .iv_size = iv_size,
! 224: .ops = af_alg_ops_create("skcipher", name),
! 225: );
! 226:
! 227: if (!this->ops)
! 228: {
! 229: free(this);
! 230: return NULL;
! 231: }
! 232: return &this->public;
! 233: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>