Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_crypter.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
! 3: *
! 4: * Permission is hereby granted, free of charge, to any person obtaining a copy
! 5: * of this software and associated documentation files (the "Software"), to deal
! 6: * in the Software without restriction, including without limitation the rights
! 7: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! 8: * copies of the Software, and to permit persons to whom the Software is
! 9: * furnished to do so, subject to the following conditions:
! 10: *
! 11: * The above copyright notice and this permission notice shall be included in
! 12: * all copies or substantial portions of the Software.
! 13: *
! 14: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! 15: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 16: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! 17: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 18: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! 19: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! 20: * THE SOFTWARE.
! 21: */
! 22:
! 23: #include "wolfssl_crypter.h"
! 24:
! 25: #include "wolfssl_common.h"
! 26: #include <wolfssl/wolfcrypt/aes.h>
! 27: #include <wolfssl/wolfcrypt/camellia.h>
! 28: #include <wolfssl/wolfcrypt/des3.h>
! 29:
! 30: #include <utils/debug.h>
! 31:
! 32: typedef struct private_wolfssl_crypter_t private_wolfssl_crypter_t;
! 33:
! 34: #define CTR_SALT_LEN 4
! 35:
! 36: /**
! 37: * Private data of wolfssl_crypter_t
! 38: */
! 39: struct private_wolfssl_crypter_t {
! 40:
! 41: /**
! 42: * Public part of this class.
! 43: */
! 44: wolfssl_crypter_t public;
! 45:
! 46: /**
! 47: * wolfSSL cipher
! 48: */
! 49: union {
! 50: #if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
! 51: Aes aes;
! 52: #endif
! 53: #ifdef HAVE_CAMELLIA
! 54: Camellia camellia;
! 55: #endif
! 56: #ifndef NO_DES3
! 57: Des des;
! 58: Des3 des3;
! 59: #endif
! 60: } cipher;
! 61:
! 62: /**
! 63: * Encryption algorithm identifier
! 64: */
! 65: encryption_algorithm_t alg;
! 66:
! 67: /**
! 68: * Private key
! 69: */
! 70: chunk_t key;
! 71:
! 72: /**
! 73: * Salt value
! 74: */
! 75: chunk_t salt;
! 76:
! 77: /**
! 78: * Size of block
! 79: */
! 80: size_t block_size;
! 81:
! 82: /**
! 83: * Size of IV
! 84: */
! 85: size_t iv_size;
! 86: };
! 87:
! 88: METHOD(crypter_t, decrypt, bool,
! 89: private_wolfssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
! 90: {
! 91: u_char *out;
! 92: bool success = FALSE;
! 93: int ret;
! 94: u_char nonce[AES_BLOCK_SIZE] = {0};
! 95: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 96: chunk_t d = chunk_empty;
! 97: #endif
! 98:
! 99: out = data.ptr;
! 100: if (dst)
! 101: {
! 102: *dst = chunk_alloc(data.len);
! 103: out = dst->ptr;
! 104: }
! 105:
! 106: if (this->salt.len > 0)
! 107: {
! 108: memcpy(nonce, this->salt.ptr, this->salt.len);
! 109: memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
! 110: nonce[AES_BLOCK_SIZE - 1] = 1;
! 111: }
! 112:
! 113: switch (this->alg)
! 114: {
! 115: case ENCR_NULL:
! 116: memcpy(out, data.ptr, data.len);
! 117: success = TRUE;
! 118: break;
! 119: #if !defined(NO_AES) && !defined(NO_AES_CBC)
! 120: case ENCR_AES_CBC:
! 121: ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
! 122: iv.ptr, AES_DECRYPTION);
! 123: if (ret == 0)
! 124: {
! 125: ret = wc_AesCbcDecrypt(&this->cipher.aes, out, data.ptr,
! 126: data.len);
! 127: }
! 128: success = (ret == 0);
! 129: break;
! 130: #endif
! 131: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 132: case ENCR_AES_CTR:
! 133: if (out == data.ptr)
! 134: {
! 135: d = chunk_alloc(data.len);
! 136: out = d.ptr;
! 137: }
! 138: ret = wc_AesSetKeyDirect(&this->cipher.aes, this->key.ptr,
! 139: this->key.len, nonce, AES_ENCRYPTION);
! 140: if (ret == 0)
! 141: {
! 142: ret = wc_AesCtrEncrypt(&this->cipher.aes, out, data.ptr,
! 143: data.len);
! 144: }
! 145: if (ret == 0 && out == d.ptr)
! 146: {
! 147: memcpy(data.ptr, out, data.len);
! 148: }
! 149: chunk_free(&d);
! 150: success = (ret == 0);
! 151: break;
! 152: #endif
! 153: #ifdef HAVE_CAMELLIA
! 154: case ENCR_CAMELLIA_CBC:
! 155: ret = wc_CamelliaSetKey(&this->cipher.camellia, this->key.ptr,
! 156: this->key.len, iv.ptr);
! 157: if (ret == 0)
! 158: {
! 159: ret = wc_CamelliaCbcDecrypt(&this->cipher.camellia, out,
! 160: data.ptr, data.len);
! 161: }
! 162: success = (ret == 0);
! 163: break;
! 164: #endif
! 165: #ifndef NO_DES3
! 166: case ENCR_3DES:
! 167: ret = wc_Des3_SetKey(&this->cipher.des3, this->key.ptr, iv.ptr,
! 168: DES_DECRYPTION);
! 169: if (ret == 0)
! 170: {
! 171: ret = wc_Des3_CbcDecrypt(&this->cipher.des3, out, data.ptr,
! 172: data.len);
! 173: }
! 174: success = (ret == 0);
! 175: break;
! 176: case ENCR_DES:
! 177: ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
! 178: DES_DECRYPTION);
! 179: if (ret == 0)
! 180: {
! 181: ret = wc_Des_CbcDecrypt(&this->cipher.des, out, data.ptr,
! 182: data.len);
! 183: }
! 184: if (ret == 0)
! 185: success = TRUE;
! 186: break;
! 187: #ifdef WOLFSSL_DES_ECB
! 188: case ENCR_DES_ECB:
! 189: ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
! 190: DES_DECRYPTION);
! 191: if (ret == 0)
! 192: {
! 193: ret = wc_Des_EcbDecrypt(&this->cipher.des, out, data.ptr,
! 194: data.len);
! 195: }
! 196: success = (ret == 0);
! 197: break;
! 198: #endif
! 199: #endif
! 200: default:
! 201: break;
! 202: }
! 203:
! 204: memwipe(nonce, sizeof(nonce));
! 205: return success;
! 206: }
! 207:
! 208: METHOD(crypter_t, encrypt, bool,
! 209: private_wolfssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
! 210: {
! 211: u_char *out;
! 212: bool success = FALSE;
! 213: int ret;
! 214: u_char nonce[AES_BLOCK_SIZE] = {0};
! 215: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 216: chunk_t d = chunk_empty;
! 217: #endif
! 218:
! 219: out = data.ptr;
! 220: if (dst)
! 221: {
! 222: *dst = chunk_alloc(data.len);
! 223: out = dst->ptr;
! 224: }
! 225:
! 226: if (this->salt.len > 0)
! 227: {
! 228: memcpy(nonce, this->salt.ptr, this->salt.len);
! 229: memcpy(nonce + this->salt.len, iv.ptr, this->iv_size);
! 230: nonce[AES_BLOCK_SIZE - 1] = 1;
! 231: }
! 232:
! 233: switch (this->alg)
! 234: {
! 235: case ENCR_NULL:
! 236: memcpy(out, data.ptr, data.len);
! 237: success = TRUE;
! 238: break;
! 239: #if !defined(NO_AES) && !defined(NO_AES_CBC)
! 240: case ENCR_AES_CBC:
! 241: ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
! 242: iv.ptr, AES_ENCRYPTION);
! 243: if (ret == 0)
! 244: {
! 245: ret = wc_AesCbcEncrypt(&this->cipher.aes, out, data.ptr,
! 246: data.len);
! 247: }
! 248: success = (ret == 0);
! 249: break;
! 250: #endif
! 251: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 252: case ENCR_AES_CTR:
! 253: if (out == data.ptr)
! 254: {
! 255: d = chunk_alloc(data.len);
! 256: out = d.ptr;
! 257: }
! 258: ret = wc_AesSetKeyDirect(&this->cipher.aes, this->key.ptr,
! 259: this->key.len, nonce, AES_ENCRYPTION);
! 260: if (ret == 0)
! 261: {
! 262: ret = wc_AesCtrEncrypt(&this->cipher.aes, out, data.ptr,
! 263: data.len);
! 264: }
! 265: if (ret == 0 && out == d.ptr)
! 266: {
! 267: memcpy(data.ptr, out, data.len);
! 268: }
! 269: chunk_free(&d);
! 270: success = (ret == 0);
! 271: break;
! 272: #endif
! 273: #ifdef HAVE_CAMELLIA
! 274: case ENCR_CAMELLIA_CBC:
! 275: ret = wc_CamelliaSetKey(&this->cipher.camellia, this->key.ptr,
! 276: this->key.len, iv.ptr);
! 277: if (ret == 0)
! 278: {
! 279: ret = wc_CamelliaCbcEncrypt(&this->cipher.camellia, out,
! 280: data.ptr, data.len);
! 281: }
! 282: success = (ret == 0);
! 283: break;
! 284: #endif
! 285: #ifndef NO_DES3
! 286: case ENCR_3DES:
! 287: ret = wc_Des3_SetKey(&this->cipher.des3, this->key.ptr, iv.ptr,
! 288: DES_ENCRYPTION);
! 289: if (ret == 0)
! 290: {
! 291: ret = wc_Des3_CbcEncrypt(&this->cipher.des3, out, data.ptr,
! 292: data.len);
! 293: }
! 294: success = (ret == 0);
! 295: break;
! 296: case ENCR_DES:
! 297: ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
! 298: DES_ENCRYPTION);
! 299: if (ret == 0)
! 300: {
! 301: ret = wc_Des_CbcEncrypt(&this->cipher.des, out, data.ptr,
! 302: data.len);
! 303: }
! 304: success = (ret == 0);
! 305: break;
! 306: #ifdef WOLFSSL_DES_ECB
! 307: case ENCR_DES_ECB:
! 308: ret = wc_Des_SetKey(&this->cipher.des, this->key.ptr, iv.ptr,
! 309: DES_ENCRYPTION);
! 310: if (ret == 0)
! 311: {
! 312: ret = wc_Des_EcbEncrypt(&this->cipher.des, out, data.ptr,
! 313: data.len);
! 314: }
! 315: success = (ret == 0);
! 316: break;
! 317: #endif
! 318: #endif
! 319: default:
! 320: break;
! 321: }
! 322:
! 323: return success;
! 324: }
! 325:
! 326: METHOD(crypter_t, get_block_size, size_t,
! 327: private_wolfssl_crypter_t *this)
! 328: {
! 329: return this->block_size;
! 330: }
! 331:
! 332: METHOD(crypter_t, get_iv_size, size_t,
! 333: private_wolfssl_crypter_t *this)
! 334: {
! 335: return this->iv_size;
! 336: }
! 337:
! 338: METHOD(crypter_t, get_key_size, size_t,
! 339: private_wolfssl_crypter_t *this)
! 340: {
! 341: return this->key.len + this->salt.len;
! 342: }
! 343:
! 344: METHOD(crypter_t, set_key, bool,
! 345: private_wolfssl_crypter_t *this, chunk_t key)
! 346: {
! 347: if (key.len != get_key_size(this))
! 348: {
! 349: return FALSE;
! 350: }
! 351: memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
! 352: memcpy(this->key.ptr, key.ptr, this->key.len);
! 353: return TRUE;
! 354: }
! 355:
! 356: METHOD(crypter_t, destroy, void,
! 357: private_wolfssl_crypter_t *this)
! 358: {
! 359: chunk_clear(&this->key);
! 360: chunk_clear(&this->salt);
! 361: switch (this->alg)
! 362: {
! 363: #if !defined(NO_AES) && !defined(NO_AES_CBC)
! 364: case ENCR_AES_CBC:
! 365: wc_AesFree(&this->cipher.aes);
! 366: break;
! 367: #endif
! 368: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 369: case ENCR_AES_CTR:
! 370: wc_AesFree(&this->cipher.aes);
! 371: break;
! 372: #endif
! 373: #ifndef NO_DES3
! 374: case ENCR_3DES:
! 375: wc_Des3Free(&this->cipher.des3);
! 376: break;
! 377: #endif
! 378: default:
! 379: break;
! 380: }
! 381: free(this);
! 382: }
! 383:
! 384: /*
! 385: * Described in header
! 386: */
! 387: wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
! 388: size_t key_size)
! 389: {
! 390: private_wolfssl_crypter_t *this;
! 391: size_t block_size;
! 392: size_t iv_size;
! 393: size_t salt_len = 0;
! 394: int ret = 0;
! 395:
! 396: switch (algo)
! 397: {
! 398: case ENCR_NULL:
! 399: key_size = 0;
! 400: block_size = 1;
! 401: iv_size = 0;
! 402: break;
! 403: #if !defined(NO_AES) && !defined(NO_AES_CBC)
! 404: case ENCR_AES_CBC:
! 405: switch (key_size)
! 406: {
! 407: case 0:
! 408: key_size = 16;
! 409: /* fall-through */
! 410: case 16:
! 411: case 24:
! 412: case 32:
! 413: block_size = AES_BLOCK_SIZE;
! 414: iv_size = AES_IV_SIZE;
! 415: break;
! 416: default:
! 417: return NULL;
! 418: }
! 419: break;
! 420: #endif
! 421: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 422: case ENCR_AES_CTR:
! 423: switch (key_size)
! 424: {
! 425: case 0:
! 426: key_size = 16;
! 427: /* fall-through */
! 428: case 16:
! 429: case 24:
! 430: case 32:
! 431: block_size = 1;
! 432: iv_size = 8;
! 433: salt_len = CTR_SALT_LEN;
! 434: break;
! 435: default:
! 436: return NULL;
! 437: }
! 438: break;
! 439: #endif
! 440: #ifdef HAVE_CAMELLIA
! 441: case ENCR_CAMELLIA_CBC:
! 442: switch (key_size)
! 443: {
! 444: case 0:
! 445: key_size = 16;
! 446: /* fall-through */
! 447: case 16:
! 448: case 24:
! 449: case 32:
! 450: block_size = CAMELLIA_BLOCK_SIZE;
! 451: iv_size = CAMELLIA_BLOCK_SIZE;
! 452: break;
! 453: default:
! 454: return NULL;
! 455: }
! 456: break;
! 457: #endif
! 458: #ifndef NO_DES3
! 459: case ENCR_3DES:
! 460: if (key_size != 24)
! 461: {
! 462: return NULL;
! 463: }
! 464: block_size = DES_BLOCK_SIZE;
! 465: iv_size = DES_BLOCK_SIZE;
! 466: break;
! 467: case ENCR_DES:
! 468: #ifdef WOLFSSL_DES_ECB
! 469: case ENCR_DES_ECB:
! 470: #endif
! 471: if (key_size != 8)
! 472: {
! 473: return NULL;
! 474: }
! 475: block_size = DES_BLOCK_SIZE;
! 476: iv_size = DES_BLOCK_SIZE;
! 477: break;
! 478: #endif
! 479: default:
! 480: return NULL;
! 481: }
! 482:
! 483: INIT(this,
! 484: .public = {
! 485: .crypter = {
! 486: .encrypt = _encrypt,
! 487: .decrypt = _decrypt,
! 488: .get_block_size = _get_block_size,
! 489: .get_iv_size = _get_iv_size,
! 490: .get_key_size = _get_key_size,
! 491: .set_key = _set_key,
! 492: .destroy = _destroy,
! 493: },
! 494: },
! 495: .alg = algo,
! 496: .block_size = block_size,
! 497: .iv_size = iv_size,
! 498: );
! 499:
! 500: switch (algo)
! 501: {
! 502: #if !defined(NO_AES) && !defined(NO_AES_CBC)
! 503: case ENCR_AES_CBC:
! 504: ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
! 505: break;
! 506: #endif
! 507: #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
! 508: case ENCR_AES_CTR:
! 509: ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
! 510: break;
! 511: #endif
! 512: #ifndef NO_DES3
! 513: case ENCR_3DES:
! 514: ret = wc_Des3Init(&this->cipher.des3, NULL, INVALID_DEVID);
! 515: break;
! 516: #endif
! 517: default:
! 518: break;
! 519: }
! 520: if (ret != 0)
! 521: {
! 522: free(this);
! 523: return NULL;
! 524: }
! 525:
! 526: this->key = chunk_alloc(key_size);
! 527: this->salt = chunk_alloc(salt_len);
! 528:
! 529: return &this->public;
! 530: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>