Return to wolfssl_crypter.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / wolfssl |
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: }