aboutsummaryrefslogtreecommitdiff
path: root/src/pae/aidl/aidl_psk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pae/aidl/aidl_psk.cpp')
-rw-r--r--src/pae/aidl/aidl_psk.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/pae/aidl/aidl_psk.cpp b/src/pae/aidl/aidl_psk.cpp
new file mode 100644
index 00000000..67afef0e
--- /dev/null
+++ b/src/pae/aidl/aidl_psk.cpp
@@ -0,0 +1,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;
+}