18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Crypto wrapper functions for NSS 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 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 <nspr/prtypes.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/plarenas.h> 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/plhash.h> 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/prtime.h> 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/prinrval.h> 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/prclist.h> 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nspr/prlock.h> 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nss/sechash.h> 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nss/pk11pub.h> 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int nss_hash(HASH_HashType type, unsigned int max_res_len, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_elem, const u8 *addr[], const size_t *len, 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *mac) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HASHContext *ctx; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int reslen; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = HASH_Create(type); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HASH_Begin(ctx); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HASH_Update(ctx, addr[i], len[i]); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HASH_End(ctx, mac, &reslen, max_res_len); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HASH_Destroy(ctx); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PK11Context *ctx = NULL; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PK11SlotInfo *slot; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECItem *param = NULL; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PK11SymKey *symkey = NULL; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECItem item; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int olen; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pkey[8], next, tmp; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add parity bits to the key */ 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = 0; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 7; i++) { 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = key[i]; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = (tmp >> i) | next | 1; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = tmp << (7 - i); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = next | 1; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slot = PK11_GetBestSlot(CKM_DES_ECB, NULL); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (slot == NULL) { 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NSS: PK11_GetBestSlot failed"); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt item.type = siBuffer; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt item.data = pkey; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt item.len = 8; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symkey = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginDerive, 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CKA_ENCRYPT, &item, NULL); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (symkey == NULL) { 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NSS: PK11_ImportSymKey failed"); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt param = PK11_GenerateNewParam(CKM_DES_ECB, symkey); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (param == NULL) { 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NSS: PK11_GenerateNewParam failed"); 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT, 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symkey, param); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NSS: PK11_CreateContextBySymKey(" 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CKM_DES_ECB) failed"); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PK11_CipherOp(ctx, cypher, &olen, 8, (void *) clear, 8) != 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECSuccess) { 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NSS: PK11_CipherOp failed"); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PK11_DestroyContext(ctx, PR_TRUE); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (symkey) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PK11_FreeSymKey(symkey); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (param) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECITEM_FreeItem(param, PR_TRUE); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint rc4_skip(const u8 *key, size_t keylen, size_t skip, 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *data, size_t data_len) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return nss_hash(HASH_AlgMD5, 16, num_elem, addr, len, mac); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return nss_hash(HASH_AlgSHA1, 20, num_elem, addr, len, mac); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *mac) 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return nss_hash(HASH_AlgSHA256, 32, num_elem, addr, len, mac); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_encrypt_init(const u8 *key, size_t len) 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt_deinit(void *ctx) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_decrypt_init(const u8 *key, size_t len) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt_deinit(void *ctx) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_mod_exp(const u8 *base, size_t base_len, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *power, size_t power_len, 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *modulus, size_t modulus_len, 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *result, size_t *result_len) 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher { 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *iv, const u8 *key, 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *crypt, size_t len) 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t len) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_cipher_deinit(struct crypto_cipher *ctx) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 208