xref: /aosp_15_r20/external/wpa_supplicant_8/src/pae/aidl/aidl_psk.cpp (revision 03f9172ca588f91df233974f4258bab95191f931)
1 /*
2  * WPA Supplicant - Aidl interface to access macsec PSK
3  * Copyright (c) 2023, Google Inc. All rights reserved.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include <aidl/android/hardware/macsec/IMacsecPskPlugin.h>
10 #include <android/binder_manager.h>
11 
12 extern "C"
13 {
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "utils/includes.h"
17 
18 #include "aidl_psk.h"
19 }
20 
21 using aidl::android::hardware::macsec::IMacsecPskPlugin;
22 
23 static std::shared_ptr<IMacsecPskPlugin> pskPlugin;
24 
aidl_psk_init()25 int aidl_psk_init()
26 {
27 	if (pskPlugin != NULL) {
28 		wpa_printf(MSG_ERROR, "Already connected to Macsec plugin");
29 		return 0;
30 	}
31 	std::string instanceName = std::string(IMacsecPskPlugin::descriptor) + "/default";
32 	pskPlugin = IMacsecPskPlugin::fromBinder(
33 		ndk::SpAIBinder(AServiceManager_waitForService(instanceName.c_str())));
34 
35 	if (pskPlugin == NULL) {
36 		wpa_printf(MSG_ERROR, "Cannot get Macsec PSK plugin service");
37 		return -ENODEV;
38 	}
39 
40 	return 0;
41 }
42 
aidl_psk_aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)43 int aidl_psk_aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
44 		u8 *cipher)
45 {
46 	if (pskPlugin == NULL)
47 		return -ENODEV;
48 
49 	n = n * 8;
50 
51 	const std::vector<u8> key_id(kek, kek + kek_len);
52 	const std::vector<u8> sak(plain, plain + n);
53 	std::vector<u8> out(n + 8);
54 
55 	auto aidlStatus = pskPlugin->wrapSak(key_id, sak, &out);
56 	if (!aidlStatus.isOk()) {
57 		wpa_printf(MSG_ERROR, "wrapSak return error: %s", aidlStatus.getMessage());
58 		return -ENODEV;
59 	}
60 
61 	if (out.size() != (n + 8)) {
62 		wpa_printf(MSG_ERROR, "wrapSak return size not n + 8");
63 		return -ENODEV;
64 	}
65 
66 	memcpy(cipher, out.data(), n + 8);
67 
68 	return 0;
69 }
70 
aidl_psk_aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)71 int aidl_psk_aes_unwrap(const u8 *kek, size_t kek_len, int n,
72 		const u8 *cipher, u8 *plain)
73 {
74 	if (pskPlugin == NULL)
75 		return -ENODEV;
76 
77         n++;
78 	n = n * 8;
79 	if (n < 8)
80 		return -ENODEV;
81 
82 	const std::vector<u8> key_id(kek, kek + kek_len);
83 	const std::vector<u8> sak(cipher, cipher + n);
84 	std::vector<u8> out(n - 8);
85 
86 	auto aidlStatus = pskPlugin->unwrapSak(key_id, sak, &out);
87 	if (!aidlStatus.isOk()) {
88 		return -ENODEV;
89 	}
90 
91 	if (out.size() != (n - 8)) {
92 		return -ENODEV;
93 	}
94 
95 	memcpy(plain, out.data(), n - 8);
96 
97 	return 0;
98 }
99 
aidl_psk_icv_hash(const u8 * ick,size_t ick_bytes,const u8 * msg,size_t msg_bytes,u8 * icv)100 int aidl_psk_icv_hash(const u8 *ick, size_t ick_bytes, const u8 *msg,
101 		size_t msg_bytes, u8 *icv)
102 {
103 	if (pskPlugin == NULL) {
104 		wpa_printf(MSG_ERROR, "pskPlugin not init");
105 		return -ENODEV;
106 	}
107 
108 	const std::vector<u8> key_id(ick, ick + ick_bytes);
109 	const std::vector<u8> data(msg, msg + msg_bytes);
110 	std::vector<u8> out(16);
111 
112 	auto aidlStatus = pskPlugin->calcIcv(key_id, data, &out);
113 	if (!aidlStatus.isOk()) {
114 		wpa_printf(MSG_ERROR, "calcIcv return error: %s", aidlStatus.getMessage());
115 		return -ENODEV;
116 	}
117 
118 	if (out.size() != 16) {
119 		wpa_printf(MSG_ERROR, "calcIcv out size not 16 bytes");
120 		return -ENODEV;
121 	}
122 
123 	memcpy(icv, out.data(), 16);
124 
125 	return 0;
126 }
127 
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)128 int aidl_psk_sak_aes_cmac(const u8 *cak, size_t cak_bytes, const u8 *ctx,
129 		size_t ctx_bytes, u8 *sak, size_t sak_bytes)
130 {
131 	if (pskPlugin == NULL)
132 		return -ENODEV;
133 
134 	const std::vector<u8> key_id(cak, cak + cak_bytes);
135 	const std::vector<u8> data(ctx, ctx + ctx_bytes);
136 	std::vector<u8> out(sak_bytes);
137 
138 	auto aidlStatus = pskPlugin->generateSak(key_id, data, sak_bytes, &out);
139 	if (!aidlStatus.isOk()) {
140 		return -ENODEV;
141 	}
142 
143 	if (out.size() != sak_bytes) {
144 		return -ENODEV;
145 	}
146 
147 	memcpy(sak, out.data(), sak_bytes);
148 
149 	return 0;
150 }
151