1214501Srpaulo/*
2214501Srpaulo * Crypto wrapper functions for NSS
3214501Srpaulo * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
4214501Srpaulo *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7214501Srpaulo */
8214501Srpaulo
9214501Srpaulo#include "includes.h"
10214501Srpaulo#include <nspr/prtypes.h>
11214501Srpaulo#include <nspr/plarenas.h>
12214501Srpaulo#include <nspr/plhash.h>
13214501Srpaulo#include <nspr/prtime.h>
14214501Srpaulo#include <nspr/prinrval.h>
15214501Srpaulo#include <nspr/prclist.h>
16214501Srpaulo#include <nspr/prlock.h>
17214501Srpaulo#include <nss/sechash.h>
18214501Srpaulo#include <nss/pk11pub.h>
19214501Srpaulo
20214501Srpaulo#include "common.h"
21214501Srpaulo#include "crypto.h"
22214501Srpaulo
23214501Srpaulo
24214501Srpaulostatic int nss_hash(HASH_HashType type, unsigned int max_res_len,
25214501Srpaulo		    size_t num_elem, const u8 *addr[], const size_t *len,
26214501Srpaulo		    u8 *mac)
27214501Srpaulo{
28214501Srpaulo	HASHContext *ctx;
29214501Srpaulo	size_t i;
30214501Srpaulo	unsigned int reslen;
31214501Srpaulo
32214501Srpaulo	ctx = HASH_Create(type);
33214501Srpaulo	if (ctx == NULL)
34214501Srpaulo		return -1;
35214501Srpaulo
36214501Srpaulo	HASH_Begin(ctx);
37214501Srpaulo	for (i = 0; i < num_elem; i++)
38214501Srpaulo		HASH_Update(ctx, addr[i], len[i]);
39214501Srpaulo	HASH_End(ctx, mac, &reslen, max_res_len);
40214501Srpaulo	HASH_Destroy(ctx);
41214501Srpaulo
42214501Srpaulo	return 0;
43214501Srpaulo}
44214501Srpaulo
45214501Srpaulo
46214501Srpaulovoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
47214501Srpaulo{
48214501Srpaulo	PK11Context *ctx = NULL;
49214501Srpaulo	PK11SlotInfo *slot;
50214501Srpaulo	SECItem *param = NULL;
51214501Srpaulo	PK11SymKey *symkey = NULL;
52214501Srpaulo	SECItem item;
53214501Srpaulo	int olen;
54214501Srpaulo	u8 pkey[8], next, tmp;
55214501Srpaulo	int i;
56214501Srpaulo
57214501Srpaulo	/* Add parity bits to the key */
58214501Srpaulo	next = 0;
59214501Srpaulo	for (i = 0; i < 7; i++) {
60214501Srpaulo		tmp = key[i];
61214501Srpaulo		pkey[i] = (tmp >> i) | next | 1;
62214501Srpaulo		next = tmp << (7 - i);
63214501Srpaulo	}
64214501Srpaulo	pkey[i] = next | 1;
65214501Srpaulo
66214501Srpaulo	slot = PK11_GetBestSlot(CKM_DES_ECB, NULL);
67214501Srpaulo	if (slot == NULL) {
68214501Srpaulo		wpa_printf(MSG_ERROR, "NSS: PK11_GetBestSlot failed");
69214501Srpaulo		goto out;
70214501Srpaulo	}
71214501Srpaulo
72214501Srpaulo	item.type = siBuffer;
73214501Srpaulo	item.data = pkey;
74214501Srpaulo	item.len = 8;
75214501Srpaulo	symkey = PK11_ImportSymKey(slot, CKM_DES_ECB, PK11_OriginDerive,
76214501Srpaulo				   CKA_ENCRYPT, &item, NULL);
77214501Srpaulo	if (symkey == NULL) {
78214501Srpaulo		wpa_printf(MSG_ERROR, "NSS: PK11_ImportSymKey failed");
79214501Srpaulo		goto out;
80214501Srpaulo	}
81214501Srpaulo
82214501Srpaulo	param = PK11_GenerateNewParam(CKM_DES_ECB, symkey);
83214501Srpaulo	if (param == NULL) {
84214501Srpaulo		wpa_printf(MSG_ERROR, "NSS: PK11_GenerateNewParam failed");
85214501Srpaulo		goto out;
86214501Srpaulo	}
87214501Srpaulo
88214501Srpaulo	ctx = PK11_CreateContextBySymKey(CKM_DES_ECB, CKA_ENCRYPT,
89214501Srpaulo					 symkey, param);
90214501Srpaulo	if (ctx == NULL) {
91214501Srpaulo		wpa_printf(MSG_ERROR, "NSS: PK11_CreateContextBySymKey("
92214501Srpaulo			   "CKM_DES_ECB) failed");
93214501Srpaulo		goto out;
94214501Srpaulo	}
95214501Srpaulo
96214501Srpaulo	if (PK11_CipherOp(ctx, cypher, &olen, 8, (void *) clear, 8) !=
97214501Srpaulo	    SECSuccess) {
98214501Srpaulo		wpa_printf(MSG_ERROR, "NSS: PK11_CipherOp failed");
99214501Srpaulo		goto out;
100214501Srpaulo	}
101214501Srpaulo
102214501Srpauloout:
103214501Srpaulo	if (ctx)
104214501Srpaulo		PK11_DestroyContext(ctx, PR_TRUE);
105214501Srpaulo	if (symkey)
106214501Srpaulo		PK11_FreeSymKey(symkey);
107214501Srpaulo	if (param)
108214501Srpaulo		SECITEM_FreeItem(param, PR_TRUE);
109214501Srpaulo}
110214501Srpaulo
111214501Srpaulo
112214501Srpauloint rc4_skip(const u8 *key, size_t keylen, size_t skip,
113214501Srpaulo	     u8 *data, size_t data_len)
114214501Srpaulo{
115214501Srpaulo	return -1;
116214501Srpaulo}
117214501Srpaulo
118214501Srpaulo
119214501Srpauloint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
120214501Srpaulo{
121214501Srpaulo	return nss_hash(HASH_AlgMD5, 16, num_elem, addr, len, mac);
122214501Srpaulo}
123214501Srpaulo
124214501Srpaulo
125214501Srpauloint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
126214501Srpaulo{
127214501Srpaulo	return nss_hash(HASH_AlgSHA1, 20, num_elem, addr, len, mac);
128214501Srpaulo}
129214501Srpaulo
130214501Srpaulo
131214501Srpauloint sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
132214501Srpaulo		  u8 *mac)
133214501Srpaulo{
134214501Srpaulo	return nss_hash(HASH_AlgSHA256, 32, num_elem, addr, len, mac);
135214501Srpaulo}
136214501Srpaulo
137214501Srpaulo
138214501Srpaulovoid * aes_encrypt_init(const u8 *key, size_t len)
139214501Srpaulo{
140214501Srpaulo	return NULL;
141214501Srpaulo}
142214501Srpaulo
143214501Srpaulo
144214501Srpaulovoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
145214501Srpaulo{
146214501Srpaulo}
147214501Srpaulo
148214501Srpaulo
149214501Srpaulovoid aes_encrypt_deinit(void *ctx)
150214501Srpaulo{
151214501Srpaulo}
152214501Srpaulo
153214501Srpaulo
154214501Srpaulovoid * aes_decrypt_init(const u8 *key, size_t len)
155214501Srpaulo{
156214501Srpaulo	return NULL;
157214501Srpaulo}
158214501Srpaulo
159214501Srpaulo
160214501Srpaulovoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
161214501Srpaulo{
162214501Srpaulo}
163214501Srpaulo
164214501Srpaulo
165214501Srpaulovoid aes_decrypt_deinit(void *ctx)
166214501Srpaulo{
167214501Srpaulo}
168214501Srpaulo
169214501Srpaulo
170214501Srpauloint crypto_mod_exp(const u8 *base, size_t base_len,
171214501Srpaulo		   const u8 *power, size_t power_len,
172214501Srpaulo		   const u8 *modulus, size_t modulus_len,
173214501Srpaulo		   u8 *result, size_t *result_len)
174214501Srpaulo{
175214501Srpaulo	return -1;
176214501Srpaulo}
177214501Srpaulo
178214501Srpaulo
179214501Srpaulostruct crypto_cipher {
180214501Srpaulo};
181214501Srpaulo
182214501Srpaulo
183214501Srpaulostruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
184214501Srpaulo					  const u8 *iv, const u8 *key,
185214501Srpaulo					  size_t key_len)
186214501Srpaulo{
187214501Srpaulo	return NULL;
188214501Srpaulo}
189214501Srpaulo
190214501Srpaulo
191214501Srpauloint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
192214501Srpaulo			  u8 *crypt, size_t len)
193214501Srpaulo{
194214501Srpaulo	return -1;
195214501Srpaulo}
196214501Srpaulo
197214501Srpaulo
198214501Srpauloint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
199214501Srpaulo			  u8 *plain, size_t len)
200214501Srpaulo{
201214501Srpaulo	return -1;
202214501Srpaulo}
203214501Srpaulo
204214501Srpaulo
205214501Srpaulovoid crypto_cipher_deinit(struct crypto_cipher *ctx)
206214501Srpaulo{
207214501Srpaulo}
208