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