Define MACsec HAL and ref impl
Add MACsec HAL interface and reference implementation. This allow OEM to store MACsec PSK key in secure storage and provide functions to use that key, Bug: 254108688 Test: atest VtsHalMacsecPSKPluginV1_0Test Change-Id: Iecfe4828839a1dab81989bf9b178ae41c6f46b82
This commit is contained in:
parent
59414af068
commit
690919a58b
15 changed files with 940 additions and 0 deletions
|
@ -84,6 +84,14 @@
|
|||
<regex-instance>[a-z]+/[0-9]+</regex-instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.macsec</name>
|
||||
<version>1</version>
|
||||
<interface>
|
||||
<name>IMacsecPskPlugin</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.automotive.occupant_awareness</name>
|
||||
<version>1</version>
|
||||
|
|
1
macsec/OWNERS
Normal file
1
macsec/OWNERS
Normal file
|
@ -0,0 +1 @@
|
|||
keithmok@google.com
|
40
macsec/aidl/Android.bp
Normal file
40
macsec/aidl/Android.bp
Normal file
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
aidl_interface {
|
||||
name: "android.hardware.macsec",
|
||||
vendor_available: true,
|
||||
srcs: ["android/hardware/macsec/*.aidl"],
|
||||
stability: "vintf",
|
||||
host_supported: true,
|
||||
backend: {
|
||||
java: {
|
||||
enabled: false,
|
||||
},
|
||||
rust: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.macsec;
|
||||
|
||||
/**
|
||||
* MACSEC (IEEE 802.1AE) pre-shared key plugin for wpa_supplicant
|
||||
*
|
||||
* The goal of this service is to provide function for using the MACSEC CAK
|
||||
*
|
||||
*/
|
||||
@VintfStability
|
||||
interface IMacsecPskPlugin {
|
||||
/**
|
||||
* For xTS test only inject a key to verify implementation correctness, not called in production
|
||||
*
|
||||
* @param keyId is key id to add
|
||||
* @param Connectivity Association Keys (CAK) to set
|
||||
* @param Connectivity Association Key Name (CKN) to set
|
||||
*
|
||||
*/
|
||||
void addTestKey(in byte[] keyId, in byte[] CAK, in byte[] CKN);
|
||||
|
||||
/**
|
||||
* Use ICV key do AES CMAC
|
||||
* same as ieee802_1x_icv_aes_cmac in wpa_supplicant
|
||||
*
|
||||
* @param keyId is key id to be used for AES CMAC
|
||||
* @param data, a data pointer to the buffer for calculate the ICV
|
||||
*
|
||||
* @return Integrity check value (ICV).
|
||||
*/
|
||||
byte[] calcIcv(in byte[] keyId, in byte[] data);
|
||||
|
||||
/**
|
||||
* KDF with CAK key to generate Secure Association Key (SAK)
|
||||
* same as ieee802_1x_sak_aes_cmac in wpa_supplicant
|
||||
*
|
||||
* @param keyId is key id to be used for KDF
|
||||
* @param data is key seed (random number)
|
||||
* @param sakLength generated SAK length (16 or 32)
|
||||
*
|
||||
* @return Secure Association Key (SAK).
|
||||
*/
|
||||
byte[] generateSak(in byte[] keyId, in byte[] data, in int sakLength);
|
||||
|
||||
/**
|
||||
* Encrypt using KEK key, this is same as aes_wrap with kek.key in wpa_supplicant
|
||||
* which used to wrap a SAK key
|
||||
*
|
||||
* @param keyId is key id to be used for encryption
|
||||
* @param sak is the SAK key (16 or 32 bytes) to be wrapped.
|
||||
*
|
||||
* @return wrapped data using Key Encrypting Key (KEK).
|
||||
*/
|
||||
byte[] wrapSak(in byte[] keyId, in byte[] sak);
|
||||
|
||||
/**
|
||||
* Decrypt using KEK key, this is same as aes_unwrap with kek.key in wpa_supplicant
|
||||
* which used to unwrap a SAK key
|
||||
*
|
||||
* @param keyId is key id to be used for decryption
|
||||
* @param sak is wrapped SAK key.
|
||||
*
|
||||
* @return unwrapped data using KEK key.
|
||||
*/
|
||||
byte[] unwrapSak(in byte[] keyId, in byte[] sak);
|
||||
}
|
91
macsec/aidl/android/hardware/macsec/IMacsecPskPlugin.aidl
Normal file
91
macsec/aidl/android/hardware/macsec/IMacsecPskPlugin.aidl
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.macsec;
|
||||
|
||||
/**
|
||||
* MACSEC (IEEE 802.1AE) pre-shared key plugin for wpa_supplicant
|
||||
*
|
||||
* The goal of this service is to provide function for using the MACSEC CAK
|
||||
*
|
||||
*/
|
||||
@VintfStability
|
||||
interface IMacsecPskPlugin {
|
||||
/**
|
||||
* For xTS test only inject a key to verify implementation correctness, not called in production
|
||||
*
|
||||
* @param keyId is key id to add
|
||||
* @param Connectivity Association Keys (CAK) to set
|
||||
* @param Connectivity Association Key Name (CKN) to set
|
||||
* @throws EX_ILLEGAL_ARGUMENT If CAK size is not 16 or 32 or keyID size not equals to CAK size
|
||||
*/
|
||||
void addTestKey(in byte[] keyId, in byte[] CAK, in byte[] CKN);
|
||||
|
||||
/**
|
||||
* Use ICV key do AES CMAC
|
||||
* same as ieee802_1x_icv_aes_cmac in wpa_supplicant
|
||||
*
|
||||
* @param keyId is key id to be used for AES CMAC
|
||||
* @param data, a data pointer to the buffer for calculate the ICV
|
||||
*
|
||||
* @return Integrity check value (ICV).
|
||||
* @throws EX_ILLEGAL_ARGUMENT If keyId does not exist
|
||||
*/
|
||||
byte[] calcIcv(in byte[] keyId, in byte[] data);
|
||||
|
||||
/**
|
||||
* KDF with CAK key to generate Secure Association Key (SAK)
|
||||
* same as ieee802_1x_sak_aes_cmac in wpa_supplicant
|
||||
*
|
||||
* @param keyId is key id to be used for KDF
|
||||
* @param data is key seed (random number)
|
||||
* @param sakLength generated SAK length (16 or 32)
|
||||
*
|
||||
* @return Secure Association Key (SAK).
|
||||
* @throws EX_ILLEGAL_ARGUMENT In the following cases:
|
||||
* - If keyId does not exist
|
||||
* - sakLength != 16 or 32
|
||||
* - data length < sakLength
|
||||
*/
|
||||
byte[] generateSak(in byte[] keyId, in byte[] data, in int sakLength);
|
||||
|
||||
/**
|
||||
* Encrypt using KEK key, this is same as aes_wrap with kek.key in wpa_supplicant
|
||||
* which used to wrap a SAK key
|
||||
*
|
||||
* @param keyId is key id to be used for encryption
|
||||
* @param sak is the SAK key (16 or 32 bytes) to be wrapped.
|
||||
*
|
||||
* @return wrapped data using Key Encrypting Key (KEK).
|
||||
* @throws EX_ILLEGAL_ARGUMENT In the following cases:
|
||||
* - If keyId does not exist
|
||||
* - sak size eqauls to 0 or not multiples of 8
|
||||
*/
|
||||
byte[] wrapSak(in byte[] keyId, in byte[] sak);
|
||||
|
||||
/**
|
||||
* Decrypt using KEK key, this is same as aes_unwrap with kek.key in wpa_supplicant
|
||||
* which used to unwrap a SAK key
|
||||
*
|
||||
* @param keyId is key id to be used for decryption
|
||||
* @param sak is wrapped SAK key.
|
||||
*
|
||||
* @return unwrapped data using KEK key.
|
||||
* @throws EX_ILLEGAL_ARGUMENT In the following cases:
|
||||
* - If keyId does not exist
|
||||
* - sak size <= 8 or not multiples of 8
|
||||
*/
|
||||
byte[] unwrapSak(in byte[] keyId, in byte[] sak);
|
||||
}
|
64
macsec/aidl/default/Android.bp
Normal file
64
macsec/aidl/default/Android.bp
Normal file
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.macsec-service",
|
||||
init_rc: ["android.hardware.macsec.rc"],
|
||||
vendor: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: [
|
||||
"MacsecPskPlugin.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.macsec-V1-ndk",
|
||||
"libcrypto",
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
vintf_fragments: ["android.hardware.macsec.xml"],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "android.hardware.macsec@V1-default-service.aidl_fuzzer",
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"MacsecPskPlugin.cpp",
|
||||
"fuzzer/fuzzer.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.macsec-V1-ndk",
|
||||
"libcrypto",
|
||||
"liblog",
|
||||
],
|
||||
defaults: [
|
||||
"service_fuzzer_defaults",
|
||||
],
|
||||
fuzz_config: {
|
||||
cc: [
|
||||
"keithmok@google.com",
|
||||
],
|
||||
},
|
||||
}
|
308
macsec/aidl/default/MacsecPskPlugin.cpp
Normal file
308
macsec/aidl/default/MacsecPskPlugin.cpp
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright 2023, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MacsecPskPlugin.h"
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include <android-base/format.h>
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace aidl::android::hardware::macsec {
|
||||
|
||||
constexpr auto ok = &ndk::ScopedAStatus::ok;
|
||||
|
||||
// vendor should hide the key in TEE/TA
|
||||
// CAK key can be either 16 / 32 bytes
|
||||
const std::vector<uint8_t> CAK_ID_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
const std::vector<uint8_t> CAK_KEY_1 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
std::vector<uint8_t> CKN_1 = {0x31, 0x32, 0x33, 0x34}; // maximum 16 bytes
|
||||
|
||||
const std::vector<uint8_t> CAK_ID_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
|
||||
const std::vector<uint8_t> CAK_KEY_2 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
std::vector<uint8_t> CKN_2 = {0x35, 0x36, 0x37, 0x38}; // maximum 16 bytes
|
||||
|
||||
static ndk::ScopedAStatus resultToStatus(binder_exception_t res, const std::string& msg = "") {
|
||||
if (msg.empty()) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(res);
|
||||
}
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(res, msg.c_str());
|
||||
}
|
||||
|
||||
static int omac1_aes(CMAC_CTX* ctx, const uint8_t* data, size_t data_len,
|
||||
uint8_t* mac /* 16 bytes */) {
|
||||
size_t outlen;
|
||||
|
||||
// Just reuse same key in ctx
|
||||
if (!CMAC_Reset(ctx)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!CMAC_Update(ctx, data, data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void put_be16(uint8_t* addr, uint16_t value) {
|
||||
*addr++ = value >> 8;
|
||||
*addr = value & 0xff;
|
||||
}
|
||||
|
||||
/* IEEE Std 802.1X-2010, 6.2.1 KDF */
|
||||
static int aes_kdf(CMAC_CTX* ctx, const char* label, const uint8_t* context, int ctx_bits,
|
||||
int ret_bits, uint8_t* ret) {
|
||||
const int h = 128;
|
||||
const int r = 8;
|
||||
int i, n;
|
||||
int lab_len, ctx_len, ret_len, buf_len;
|
||||
uint8_t* buf;
|
||||
|
||||
lab_len = strlen(label);
|
||||
ctx_len = (ctx_bits + 7) / 8;
|
||||
ret_len = ((ret_bits & 0xffff) + 7) / 8;
|
||||
buf_len = lab_len + ctx_len + 4;
|
||||
|
||||
memset(ret, 0, ret_len);
|
||||
|
||||
n = (ret_bits + h - 1) / h;
|
||||
if (n > ((0x1 << r) - 1)) return -1;
|
||||
|
||||
buf = (uint8_t*)calloc(1, buf_len);
|
||||
if (buf == NULL) return -1;
|
||||
|
||||
memcpy(buf + 1, label, lab_len);
|
||||
memcpy(buf + lab_len + 2, context, ctx_len);
|
||||
put_be16(&buf[buf_len - 2], ret_bits);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
int res;
|
||||
|
||||
buf[0] = (uint8_t)(i + 1);
|
||||
res = omac1_aes(ctx, buf, buf_len, ret);
|
||||
if (res) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
ret = ret + h / 8;
|
||||
}
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MacsecPskPlugin::MacsecPskPlugin() {
|
||||
// always make sure ckn is 16 bytes, zero padded
|
||||
CKN_1.resize(16);
|
||||
CKN_2.resize(16);
|
||||
|
||||
addTestKey(CAK_ID_1, CAK_KEY_1, CKN_1);
|
||||
addTestKey(CAK_ID_2, CAK_KEY_2, CKN_2);
|
||||
}
|
||||
|
||||
MacsecPskPlugin::~MacsecPskPlugin() {
|
||||
for (auto s : mKeys) {
|
||||
OPENSSL_cleanse(&s.kekEncCtx, sizeof(AES_KEY));
|
||||
OPENSSL_cleanse(&s.kekDecCtx, sizeof(AES_KEY));
|
||||
CMAC_CTX_free(s.ickCtx);
|
||||
CMAC_CTX_free(s.cakCtx);
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus MacsecPskPlugin::addTestKey(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& CAK,
|
||||
const std::vector<uint8_t>& CKN) {
|
||||
if (CAK.size() != 16 && CAK.size() != 32) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "CAK length must be 16 or 32 bytes");
|
||||
}
|
||||
|
||||
if (keyId.size() != CAK.size()) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key ID must be same as CAK length");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ckn;
|
||||
ckn = CKN;
|
||||
ckn.resize(16); // make sure it is always zero padded with maximum length of
|
||||
// 16 bytes
|
||||
|
||||
AES_KEY kekEncCtx;
|
||||
AES_KEY kekDecCtx;
|
||||
CMAC_CTX* ickCtx;
|
||||
CMAC_CTX* cakCtx;
|
||||
|
||||
// Create the CAK openssl context
|
||||
cakCtx = CMAC_CTX_new();
|
||||
|
||||
CMAC_Init(cakCtx, CAK.data(), CAK.size(),
|
||||
CAK.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
|
||||
|
||||
// derive KEK from CAK (ieee802_1x_kek_aes_cmac)
|
||||
std::vector<uint8_t> kek;
|
||||
kek.resize(CAK.size());
|
||||
|
||||
aes_kdf(cakCtx, "IEEE8021 KEK", (const uint8_t*)ckn.data(), ckn.size() * 8, 8 * kek.size(),
|
||||
kek.data());
|
||||
|
||||
AES_set_encrypt_key(kek.data(), kek.size() << 3, &kekEncCtx);
|
||||
AES_set_decrypt_key(kek.data(), kek.size() << 3, &kekDecCtx);
|
||||
|
||||
// derive ICK from CAK (ieee802_1x_ick_aes_cmac)
|
||||
std::vector<uint8_t> ick;
|
||||
ick.resize(CAK.size());
|
||||
|
||||
aes_kdf(cakCtx, "IEEE8021 ICK", (const uint8_t*)CKN.data(), CKN.size() * 8, 8 * ick.size(),
|
||||
ick.data());
|
||||
|
||||
ickCtx = CMAC_CTX_new();
|
||||
|
||||
CMAC_Init(ickCtx, ick.data(), ick.size(),
|
||||
ick.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
|
||||
|
||||
mKeys.push_back({keyId, kekEncCtx, kekDecCtx, ickCtx, cakCtx});
|
||||
|
||||
return ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus MacsecPskPlugin::calcIcv(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& data,
|
||||
std::vector<uint8_t>* out) {
|
||||
CMAC_CTX* ctx = NULL;
|
||||
|
||||
for (auto s : mKeys) {
|
||||
if (s.keyId == keyId) {
|
||||
ctx = s.ickCtx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
|
||||
}
|
||||
|
||||
out->resize(16);
|
||||
if (omac1_aes(ctx, data.data(), data.size(), out->data()) != 0) {
|
||||
return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
|
||||
}
|
||||
|
||||
return ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus MacsecPskPlugin::generateSak(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& data,
|
||||
const int sakLength, std::vector<uint8_t>* out) {
|
||||
CMAC_CTX* ctx = NULL;
|
||||
|
||||
if ((sakLength != 16) && (sakLength != 32)) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid SAK length");
|
||||
}
|
||||
|
||||
if (data.size() < sakLength) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid data length");
|
||||
}
|
||||
|
||||
for (auto s : mKeys) {
|
||||
if (s.keyId == keyId) {
|
||||
ctx = s.cakCtx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
|
||||
}
|
||||
|
||||
out->resize(sakLength);
|
||||
|
||||
if (aes_kdf(ctx, "IEEE8021 SAK", data.data(), data.size() * 8, out->size() * 8, out->data()) !=
|
||||
0) {
|
||||
return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
|
||||
}
|
||||
|
||||
return ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus MacsecPskPlugin::wrapSak(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& sak,
|
||||
std::vector<uint8_t>* out) {
|
||||
if (sak.size() == 0 || sak.size() % 8 != 0) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT,
|
||||
"SAK length not multiple of 8 or greater than 0");
|
||||
}
|
||||
|
||||
AES_KEY* ctx = NULL;
|
||||
|
||||
for (auto s : mKeys) {
|
||||
if (s.keyId == keyId) {
|
||||
ctx = &s.kekEncCtx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
|
||||
}
|
||||
|
||||
out->resize(sak.size() + 8);
|
||||
|
||||
if (AES_wrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
|
||||
return ok();
|
||||
}
|
||||
|
||||
return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus MacsecPskPlugin::unwrapSak(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& sak,
|
||||
std::vector<uint8_t>* out) {
|
||||
if (sak.size() <= 8 || sak.size() % 8 != 0) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT,
|
||||
"SAK length not multiple of 8 or greater than 0");
|
||||
}
|
||||
|
||||
AES_KEY* ctx = NULL;
|
||||
|
||||
for (auto s : mKeys) {
|
||||
if (s.keyId == keyId) {
|
||||
ctx = &s.kekDecCtx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
|
||||
}
|
||||
|
||||
out->resize(sak.size() - 8);
|
||||
|
||||
if (AES_unwrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
|
||||
return ok();
|
||||
}
|
||||
|
||||
return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::macsec
|
57
macsec/aidl/default/MacsecPskPlugin.h
Normal file
57
macsec/aidl/default/MacsecPskPlugin.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2023, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/macsec/BnMacsecPskPlugin.h>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
namespace aidl::android::hardware::macsec {
|
||||
|
||||
struct keys {
|
||||
std::vector<uint8_t> keyId;
|
||||
AES_KEY kekEncCtx;
|
||||
AES_KEY kekDecCtx;
|
||||
CMAC_CTX* ickCtx;
|
||||
CMAC_CTX* cakCtx;
|
||||
};
|
||||
|
||||
class MacsecPskPlugin : public BnMacsecPskPlugin {
|
||||
public:
|
||||
MacsecPskPlugin();
|
||||
~MacsecPskPlugin();
|
||||
ndk::ScopedAStatus addTestKey(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& CAK,
|
||||
const std::vector<uint8_t>& CKN) override;
|
||||
ndk::ScopedAStatus calcIcv(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& data,
|
||||
std::vector<uint8_t>* out) override;
|
||||
|
||||
ndk::ScopedAStatus generateSak(const std::vector<uint8_t>& keyId,
|
||||
const std::vector<uint8_t>& data, const int sakLength,
|
||||
std::vector<uint8_t>* out);
|
||||
|
||||
ndk::ScopedAStatus wrapSak(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& sak,
|
||||
std::vector<uint8_t>* out) override;
|
||||
|
||||
ndk::ScopedAStatus unwrapSak(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& sak,
|
||||
std::vector<uint8_t>* out) override;
|
||||
|
||||
private:
|
||||
std::vector<struct keys> mKeys;
|
||||
};
|
||||
} // namespace aidl::android::hardware::macsec
|
3
macsec/aidl/default/android.hardware.macsec.rc
Normal file
3
macsec/aidl/default/android.hardware.macsec.rc
Normal file
|
@ -0,0 +1,3 @@
|
|||
service android.hardware.macsec /vendor/bin/hw/android.hardware.macsec-service
|
||||
class early_hal
|
||||
user nobody
|
26
macsec/aidl/default/android.hardware.macsec.xml
Normal file
26
macsec/aidl/default/android.hardware.macsec.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.macsec</name>
|
||||
<version>1</version>
|
||||
<interface>
|
||||
<name>IMacsecPskPlugin</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
27
macsec/aidl/default/fuzzer/fuzzer.cpp
Normal file
27
macsec/aidl/default/fuzzer/fuzzer.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <fuzzbinder/libbinder_ndk_driver.h>
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
#include "MacsecPskPlugin.h"
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
std::shared_ptr<aidl::android::hardware::macsec::MacsecPskPlugin> service =
|
||||
ndk::SharedRefBase::make<aidl::android::hardware::macsec::MacsecPskPlugin>();
|
||||
android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
|
||||
|
||||
return 0;
|
||||
}
|
43
macsec/aidl/default/service.cpp
Normal file
43
macsec/aidl/default/service.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2023, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MacsecPskPlugin.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
namespace android::hardware::macsec {
|
||||
|
||||
using namespace std::string_literals;
|
||||
using ::aidl::android::hardware::macsec::MacsecPskPlugin;
|
||||
|
||||
extern "C" int main() {
|
||||
base::SetDefaultTag("MacsecPskPlugin");
|
||||
base::SetMinimumLogSeverity(base::VERBOSE);
|
||||
|
||||
LOG(VERBOSE) << "Starting up...";
|
||||
auto service = ndk::SharedRefBase::make<MacsecPskPlugin>();
|
||||
const auto instance = MacsecPskPlugin::descriptor + "/default"s;
|
||||
const auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
|
||||
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance;
|
||||
LOG(VERBOSE) << "Started successfully!";
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
LOG(FATAL) << "MacsecPskPlugin exited unexpectedly!";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} // namespace android::hardware::macsec
|
48
macsec/aidl/vts/functional/Android.bp
Normal file
48
macsec/aidl/vts/functional/Android.bp
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalMacsecPskPluginV1Test",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
cpp_std: "experimental",
|
||||
srcs: [
|
||||
"MacsecAidlTest.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.macsec-V1-ndk",
|
||||
"libgmock",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
142
macsec/aidl/vts/functional/MacsecAidlTest.cpp
Normal file
142
macsec/aidl/vts/functional/MacsecAidlTest.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/macsec/IMacsecPskPlugin.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using aidl::android::hardware::macsec::IMacsecPskPlugin;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace std::string_literals;
|
||||
|
||||
const std::vector<uint8_t> CAK_ID_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
|
||||
const std::vector<uint8_t> CAK_KEY_1 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
const std::vector<uint8_t> CKN_1 = {0x31, 0x32, 0x33, 0x34}; // maximum 16 bytes
|
||||
const std::vector<uint8_t> SAK_DATA_1 = {0x31, 0x32, 0x33, 0x34, 0x11, 0x12, 0x12, 0x14,
|
||||
0x31, 0x32, 0x33, 0x34, 0x11, 0x12, 0x12, 0x14};
|
||||
const std::vector<uint8_t> SAK_1 = {0x13, 0xD9, 0xEE, 0x5B, 0x26, 0x8B, 0x44, 0xFB,
|
||||
0x37, 0x63, 0x3D, 0x41, 0xC8, 0xE7, 0x0D, 0x93};
|
||||
const std::vector<uint8_t> WRAPPED_SAK_1 = {0x3B, 0x39, 0xAB, 0x4C, 0xD8, 0xDA, 0x2E, 0xC5,
|
||||
0xD1, 0x38, 0x6A, 0x13, 0x9D, 0xE3, 0x78, 0xD9,
|
||||
0x93, 0xD2, 0xA0, 0x70, 0x88, 0xCB, 0xF5, 0xEC};
|
||||
const std::vector<uint8_t> DATA_1 = {0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x34, 0x29,
|
||||
0x51, 0x52, 0x53, 0x54, 0x51, 0x35, 0x54, 0x59};
|
||||
const std::vector<uint8_t> ICV_1 = {0xDF, 0x54, 0xFF, 0xCD, 0xE0, 0xA9, 0x78, 0x10,
|
||||
0x6B, 0x7B, 0xD2, 0xBF, 0xEF, 0xD9, 0x0C, 0x81};
|
||||
|
||||
const std::vector<uint8_t> CAK_ID_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02};
|
||||
const std::vector<uint8_t> CAK_KEY_2 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
const std::vector<uint8_t> CKN_2 = {0x35, 0x36, 0x37, 0x38}; // maximum 16 bytes
|
||||
const std::vector<uint8_t> SAK_DATA_2 = {0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
|
||||
0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
|
||||
0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
|
||||
0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34};
|
||||
const std::vector<uint8_t> SAK_2 = {0x39, 0x09, 0x36, 0x60, 0x18, 0x07, 0x2B, 0x5D,
|
||||
0xF0, 0x81, 0x81, 0x45, 0xCD, 0x71, 0xC6, 0xBA,
|
||||
0x1D, 0x2B, 0x87, 0xC4, 0xEF, 0x79, 0x68, 0x82,
|
||||
0x28, 0xD0, 0x25, 0x86, 0xD3, 0x63, 0xFF, 0x89};
|
||||
const std::vector<uint8_t> WRAPPED_SAK_2 = {
|
||||
0x2f, 0x6a, 0x22, 0x29, 0x68, 0x0e, 0x6e, 0x35, 0x91, 0x64, 0x05, 0x4a, 0x31, 0x8d,
|
||||
0x35, 0xea, 0x95, 0x85, 0x40, 0xc6, 0xea, 0x55, 0xe5, 0xc5, 0x68, 0x40, 0xae, 0x4d,
|
||||
0x6f, 0xeb, 0x73, 0xcd, 0x4e, 0x2a, 0x43, 0xb1, 0xda, 0x49, 0x4f, 0x0a};
|
||||
const std::vector<uint8_t> DATA_2 = {0x71, 0x82, 0x13, 0x24, 0x31, 0x82, 0xA4, 0x2F,
|
||||
0x51, 0x52, 0x53, 0x44, 0x21, 0x35, 0x54, 0x59};
|
||||
const std::vector<uint8_t> ICV_2 = {0x8D, 0xF1, 0x1D, 0x6E, 0xAC, 0x62, 0xC1, 0x2A,
|
||||
0xE8, 0xF8, 0x4E, 0xB1, 0x00, 0x45, 0x9A, 0xAD};
|
||||
|
||||
class MacsecAidlTest : public ::testing::TestWithParam<std::string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
android::base::SetDefaultTag("MACSEC_HAL_VTS");
|
||||
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
|
||||
const auto instance = IMacsecPskPlugin::descriptor + "/default"s;
|
||||
mMacsecPskPluginService = IMacsecPskPlugin::fromBinder(
|
||||
ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
|
||||
|
||||
ASSERT_NE(mMacsecPskPluginService, nullptr);
|
||||
auto aidlStatus = mMacsecPskPluginService->addTestKey(CAK_ID_1, CAK_KEY_1, CKN_1);
|
||||
ASSERT_TRUE(aidlStatus.isOk());
|
||||
aidlStatus = mMacsecPskPluginService->addTestKey(CAK_ID_2, CAK_KEY_2, CKN_2);
|
||||
ASSERT_TRUE(aidlStatus.isOk());
|
||||
}
|
||||
virtual void TearDown() override {}
|
||||
|
||||
std::shared_ptr<IMacsecPskPlugin> mMacsecPskPluginService;
|
||||
};
|
||||
|
||||
TEST_P(MacsecAidlTest, calcIcv) {
|
||||
std::vector<uint8_t> out;
|
||||
auto aidlStatus = mMacsecPskPluginService->calcIcv(CAK_ID_1, DATA_1, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "calcIcv KEY 1 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, ICV_1);
|
||||
|
||||
aidlStatus = mMacsecPskPluginService->calcIcv(CAK_ID_2, DATA_2, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "calcIcv KEY 2 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, ICV_2);
|
||||
}
|
||||
|
||||
TEST_P(MacsecAidlTest, generateSak) {
|
||||
std::vector<uint8_t> out;
|
||||
auto aidlStatus = mMacsecPskPluginService->generateSak(CAK_ID_1, SAK_DATA_1, 16, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "generateSak KEY 1 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, SAK_1);
|
||||
|
||||
aidlStatus = mMacsecPskPluginService->generateSak(CAK_ID_2, SAK_DATA_2, 32, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "generateSak KEY 2 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, SAK_2);
|
||||
}
|
||||
|
||||
TEST_P(MacsecAidlTest, wrapSak) {
|
||||
std::vector<uint8_t> out;
|
||||
auto aidlStatus = mMacsecPskPluginService->wrapSak(CAK_ID_1, SAK_1, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "wrapSak KEY 1 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, WRAPPED_SAK_1);
|
||||
|
||||
aidlStatus = mMacsecPskPluginService->wrapSak(CAK_ID_2, SAK_2, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "wrapSak KEY 2 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, WRAPPED_SAK_2);
|
||||
}
|
||||
|
||||
TEST_P(MacsecAidlTest, unwrapSak) {
|
||||
std::vector<uint8_t> out;
|
||||
auto aidlStatus = mMacsecPskPluginService->unwrapSak(CAK_ID_1, WRAPPED_SAK_1, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "unwrapSak KEY 1 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, SAK_1);
|
||||
|
||||
aidlStatus = mMacsecPskPluginService->unwrapSak(CAK_ID_2, WRAPPED_SAK_2, &out);
|
||||
ASSERT_TRUE(aidlStatus.isOk()) << "unwrapSak KEY 2 failed: " << aidlStatus.getMessage();
|
||||
EXPECT_EQ(out, SAK_2);
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MacsecAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, MacsecAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IMacsecPskPlugin::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
2
macsec/aidl/vts/functional/OWNERS
Normal file
2
macsec/aidl/vts/functional/OWNERS
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Bug component: 533426
|
||||
keithmok@google.com
|
Loading…
Reference in a new issue