1/*
2 *  vmdh.c
3 *  Security
4 *
5 *  Created by Michael Brouwer on 11/7/06.
6 *  Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
7 *
8 */
9
10/*!
11	@header vmdh
12	The functions provided in vmdh.h implement the crypto exchange required
13    for a Diffie-Hellman voicemail exchange.
14*/
15
16
17#include "vmdh.h"
18#include <CommonCrypto/CommonCryptor.h>
19#include <utilities/debugging.h>
20#include <string.h>
21#include <Security/SecInternal.h>
22#include <Security/SecDH.h>
23
24vmdh_t vmdh_create(uint32_t g, const uint8_t *p, size_t p_len,
25    const uint8_t *recip, size_t recip_len) {
26	SecDHContext dh;
27	if (SecDHCreate(g, p, p_len, 0/*l*/, recip, recip_len, &dh))
28		return NULL;
29	return (vmdh_t)dh;
30}
31
32bool vmdh_generate_key(vmdh_t vmdh, uint8_t *pub_key, size_t *pub_key_len) {
33	return !SecDHGenerateKeypair((SecDHContext)vmdh, pub_key, pub_key_len);
34}
35
36bool vmdh_encrypt_password(vmdh_t vmdh,
37	const uint8_t *pub_key, size_t pub_key_len,
38    const uint8_t *pw, size_t pw_len, uint8_t *encpw, size_t *encpw_len) {
39	uint8_t aes_key[kCCKeySizeAES128];
40	size_t aes_key_len = kCCKeySizeAES128;
41
42	if (SecDHComputeKey((SecDHContext)vmdh, pub_key, pub_key_len,
43		aes_key, &aes_key_len)) {
44		return false;
45	}
46
47    /* Use the first 16 bytes in aes_key as an AES key. */
48	if (CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
49		kCCOptionPKCS7Padding, aes_key, kCCKeySizeAES128, NULL,
50		pw, pw_len, encpw, *encpw_len, encpw_len)) {
51		return false;
52	}
53
54	/* Zero out key material. */
55	bzero(aes_key, kCCKeySizeAES128);
56
57    return true;
58}
59
60void vmdh_destroy(vmdh_t vmdh) {
61    return SecDHDestroy((SecDHContext)vmdh);
62}
63