18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / wrapper functions for libgcrypt 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <gcrypt.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_hd_t hd; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *p; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR) 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_write(hd, addr[i], len[i]); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = gcry_md_read(hd, GCRY_MD_MD4); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4)); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_close(hd); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pkey[8], next, tmp; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add parity bits to the key */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = 0; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 7; i++) { 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = key[i]; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = (tmp >> i) | next | 1; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = tmp << (7 - i); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = next | 1; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_err_code(gcry_cipher_setkey(hd, pkey, 8)); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_encrypt(hd, cypher, 8, clear, 8); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(hd); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_hd_t hd; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *p; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_write(hd, addr[i], len[i]); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = gcry_md_read(hd, GCRY_MD_MD5); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5)); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_close(hd); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_hd_t hd; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *p; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_write(hd, addr[i], len[i]); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = gcry_md_read(hd, GCRY_MD_SHA1); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1)); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_md_close(hd); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_encrypt_init(const u8 *key, size_t len) 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("cipher open failed\n"); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("setkey failed\n"); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(hd); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hd; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd = ctx; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_encrypt(hd, crypt, 16, plain, 16); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt_deinit(void *ctx) 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd = ctx; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(hd); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_decrypt_init(const u8 *key, size_t len) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(hd); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hd; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd = ctx; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_decrypt(hd, plain, 16, crypt, 16); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt_deinit(void *ctx) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t hd = ctx; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(hd); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_mod_exp(const u8 *base, size_t base_len, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *power, size_t power_len, 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *modulus, size_t modulus_len, 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *result, size_t *result_len) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL, 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bn_result = NULL; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) != 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR || 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) != 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR || 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len, 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL) != GPG_ERR_NO_ERROR) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto error; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bn_result = gcry_mpi_new(modulus_len * 8); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bn_result) != GPG_ERR_NO_ERROR) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto error; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterror: 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_release(bn_base); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_release(bn_exp); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_release(bn_modulus); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_mpi_release(bn_result); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher { 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t enc; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_hd_t dec; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *iv, const u8 *key, 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_cipher *ctx; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_error_t res; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum gcry_cipher_algos a; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ivlen; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC4: 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_ARCFOUR; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM, 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_AES: 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len == 24) 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_AES192; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (key_len == 32) 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_AES256; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_AES; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_3DES: 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_3DES; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_DES: 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_DES; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC2: 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len == 5) 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_RFC2268_40; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = GCRY_CIPHER_RFC2268_128; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != GPG_ERR_NO_ERROR) { 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR || 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->enc); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->dec); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ivlen = gcry_cipher_get_algo_blklen(a); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR || 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->enc); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->dec); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ctx; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *crypt, size_t len) 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) != 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t len) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) != 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GPG_ERR_NO_ERROR) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_cipher_deinit(struct crypto_cipher *ctx) 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->enc); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gcry_cipher_close(ctx->dec); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 300