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