aboutsummaryrefslogtreecommitdiff
path: root/src/pae/aidl/aidl_psk.cpp
blob: 67afef0edace3a804a7bcd7c1e38b38effd7c9e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * WPA Supplicant - Aidl interface to access macsec PSK
 * Copyright (c) 2023, Google Inc. All rights reserved.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include <aidl/android/hardware/macsec/IMacsecPskPlugin.h>
#include <android/binder_manager.h>

extern "C"
{
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/includes.h"

#include "aidl_psk.h"
}

using aidl::android::hardware::macsec::IMacsecPskPlugin;

static std::shared_ptr<IMacsecPskPlugin> pskPlugin;

int aidl_psk_init()
{
	if (pskPlugin != NULL) {
		wpa_printf(MSG_ERROR, "Already connected to Macsec plugin");
		return 0;
	}
	std::string instanceName = std::string(IMacsecPskPlugin::descriptor) + "/default";
	pskPlugin = IMacsecPskPlugin::fromBinder(
		ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));

	if (pskPlugin == NULL) {
		wpa_printf(MSG_ERROR, "Cannot get Macsec PSK plugin service");
		return -ENODEV;
	}

	return 0;
}

int aidl_psk_aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
		u8 *cipher)
{
	if (pskPlugin == NULL)
		return -ENODEV;

	n = n * 8;

	const std::vector<u8> key_id(kek, kek + kek_len);
	const std::vector<u8> sak(plain, plain + n);
	std::vector<u8> out(n + 8);

	auto aidlStatus = pskPlugin->wrapSak(key_id, sak, &out);
	if (!aidlStatus.isOk()) {
		wpa_printf(MSG_ERROR, "wrapSak return error: %s", aidlStatus.getMessage());
		return -ENODEV;
	}

	if (out.size() != (n + 8)) {
		wpa_printf(MSG_ERROR, "wrapSak return size not n + 8");
		return -ENODEV;
	}

	memcpy(cipher, out.data(), n + 8);

	return 0;
}

int aidl_psk_aes_unwrap(const u8 *kek, size_t kek_len, int n,
		const u8 *cipher, u8 *plain)
{
	if (pskPlugin == NULL)
		return -ENODEV;

	n = n * 8;
	if (n < 8)
		return -ENODEV;

	const std::vector<u8> key_id(kek, kek + kek_len);
	const std::vector<u8> sak(cipher, cipher + n);
	std::vector<u8> out(n - 8);

	auto aidlStatus = pskPlugin->unwrapSak(key_id, sak, &out);
	if (!aidlStatus.isOk()) {
		return -ENODEV;
	}

	if (out.size() != (n - 8)) {
		return -ENODEV;
	}

	memcpy(plain, out.data(), n - 8);

	return 0;
}

int aidl_psk_icv_hash(const u8 *ick, size_t ick_bytes, const u8 *msg,
		size_t msg_bytes, u8 *icv)
{
	if (pskPlugin == NULL) {
		wpa_printf(MSG_ERROR, "pskPlugin not init");
		return -ENODEV;
	}

	const std::vector<u8> key_id(ick, ick + ick_bytes);
	const std::vector<u8> data(msg, msg + msg_bytes);
	std::vector<u8> out(16);

	auto aidlStatus = pskPlugin->calcIcv(key_id, data, &out);
	if (!aidlStatus.isOk()) {
		wpa_printf(MSG_ERROR, "calcIcv return error: %s", aidlStatus.getMessage());
		return -ENODEV;
	}

	if (out.size() != 16) {
		wpa_printf(MSG_ERROR, "calcIcv out size not 16 bytes");
		return -ENODEV;
	}

	memcpy(icv, out.data(), 16);

	return 0;
}

int aidl_psk_sak_aes_cmac(const u8 *cak, size_t cak_bytes, const u8 *ctx,
		size_t ctx_bytes, u8 *sak, size_t sak_bytes)
{
	if (pskPlugin == NULL)
		return -ENODEV;

	const std::vector<u8> key_id(cak, cak + cak_bytes);
	const std::vector<u8> data(ctx, ctx + ctx_bytes);
	std::vector<u8> out(sak_bytes);

	auto aidlStatus = pskPlugin->generateSak(key_id, data, sak_bytes, &out);
	if (!aidlStatus.isOk()) {
		return -ENODEV;
	}

	if (out.size() != sak_bytes) {
		return -ENODEV;
	}

	memcpy(sak, out.data(), sak_bytes);

	return 0;
}