xref: /aosp_15_r20/hardware/interfaces/macsec/aidl/default/MacsecPskPlugin.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright 2023, The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include "MacsecPskPlugin.h"
18*4d7e907cSAndroid Build Coastguard Worker #include <openssl/cipher.h>
19*4d7e907cSAndroid Build Coastguard Worker #include <openssl/mem.h>
20*4d7e907cSAndroid Build Coastguard Worker 
21*4d7e907cSAndroid Build Coastguard Worker #include <android-base/format.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
23*4d7e907cSAndroid Build Coastguard Worker 
24*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::macsec {
25*4d7e907cSAndroid Build Coastguard Worker 
26*4d7e907cSAndroid Build Coastguard Worker constexpr auto ok = &ndk::ScopedAStatus::ok;
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker // vendor should hide the key in TEE/TA
29*4d7e907cSAndroid Build Coastguard Worker // CAK key can be either 16 / 32 bytes
30*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> CAK_ID_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31*4d7e907cSAndroid Build Coastguard Worker                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
32*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> CAK_KEY_1 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
33*4d7e907cSAndroid Build Coastguard Worker                                         0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
34*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> CKN_1 = {0x31, 0x32, 0x33, 0x34};  // maximum 16 bytes
35*4d7e907cSAndroid Build Coastguard Worker 
36*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> CAK_ID_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37*4d7e907cSAndroid Build Coastguard Worker                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38*4d7e907cSAndroid Build Coastguard Worker                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39*4d7e907cSAndroid Build Coastguard Worker                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
40*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> CAK_KEY_2 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
41*4d7e907cSAndroid Build Coastguard Worker                                         0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
42*4d7e907cSAndroid Build Coastguard Worker                                         0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
43*4d7e907cSAndroid Build Coastguard Worker                                         0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
44*4d7e907cSAndroid Build Coastguard Worker std::vector<uint8_t> CKN_2 = {0x35, 0x36, 0x37, 0x38};  // maximum 16 bytes
45*4d7e907cSAndroid Build Coastguard Worker 
resultToStatus(binder_exception_t res,const std::string & msg="")46*4d7e907cSAndroid Build Coastguard Worker static ndk::ScopedAStatus resultToStatus(binder_exception_t res, const std::string& msg = "") {
47*4d7e907cSAndroid Build Coastguard Worker     if (msg.empty()) {
48*4d7e907cSAndroid Build Coastguard Worker         return ndk::ScopedAStatus::fromExceptionCode(res);
49*4d7e907cSAndroid Build Coastguard Worker     }
50*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::fromExceptionCodeWithMessage(res, msg.c_str());
51*4d7e907cSAndroid Build Coastguard Worker }
52*4d7e907cSAndroid Build Coastguard Worker 
omac1_aes(CMAC_CTX * ctx,const uint8_t * data,size_t data_len,uint8_t * mac)53*4d7e907cSAndroid Build Coastguard Worker static int omac1_aes(CMAC_CTX* ctx, const uint8_t* data, size_t data_len,
54*4d7e907cSAndroid Build Coastguard Worker                      uint8_t* mac /* 16 bytes */) {
55*4d7e907cSAndroid Build Coastguard Worker     size_t outlen;
56*4d7e907cSAndroid Build Coastguard Worker 
57*4d7e907cSAndroid Build Coastguard Worker     // Just reuse same key in ctx
58*4d7e907cSAndroid Build Coastguard Worker     if (!CMAC_Reset(ctx)) {
59*4d7e907cSAndroid Build Coastguard Worker         return -1;
60*4d7e907cSAndroid Build Coastguard Worker     }
61*4d7e907cSAndroid Build Coastguard Worker 
62*4d7e907cSAndroid Build Coastguard Worker     if (!CMAC_Update(ctx, data, data_len)) {
63*4d7e907cSAndroid Build Coastguard Worker         return -1;
64*4d7e907cSAndroid Build Coastguard Worker     }
65*4d7e907cSAndroid Build Coastguard Worker 
66*4d7e907cSAndroid Build Coastguard Worker     if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16) {
67*4d7e907cSAndroid Build Coastguard Worker         return -1;
68*4d7e907cSAndroid Build Coastguard Worker     }
69*4d7e907cSAndroid Build Coastguard Worker     return 0;
70*4d7e907cSAndroid Build Coastguard Worker }
71*4d7e907cSAndroid Build Coastguard Worker 
put_be16(uint8_t * addr,uint16_t value)72*4d7e907cSAndroid Build Coastguard Worker static void put_be16(uint8_t* addr, uint16_t value) {
73*4d7e907cSAndroid Build Coastguard Worker     *addr++ = value >> 8;
74*4d7e907cSAndroid Build Coastguard Worker     *addr = value & 0xff;
75*4d7e907cSAndroid Build Coastguard Worker }
76*4d7e907cSAndroid Build Coastguard Worker 
77*4d7e907cSAndroid Build Coastguard Worker /* IEEE Std 802.1X-2010, 6.2.1 KDF */
aes_kdf(CMAC_CTX * ctx,const char * label,const uint8_t * context,int ctx_bits,int ret_bits,uint8_t * ret)78*4d7e907cSAndroid Build Coastguard Worker static int aes_kdf(CMAC_CTX* ctx, const char* label, const uint8_t* context, int ctx_bits,
79*4d7e907cSAndroid Build Coastguard Worker                    int ret_bits, uint8_t* ret) {
80*4d7e907cSAndroid Build Coastguard Worker     const int h = 128;
81*4d7e907cSAndroid Build Coastguard Worker     const int r = 8;
82*4d7e907cSAndroid Build Coastguard Worker     int i, n;
83*4d7e907cSAndroid Build Coastguard Worker     int lab_len, ctx_len, ret_len, buf_len;
84*4d7e907cSAndroid Build Coastguard Worker     uint8_t* buf;
85*4d7e907cSAndroid Build Coastguard Worker 
86*4d7e907cSAndroid Build Coastguard Worker     lab_len = strlen(label);
87*4d7e907cSAndroid Build Coastguard Worker     ctx_len = (ctx_bits + 7) / 8;
88*4d7e907cSAndroid Build Coastguard Worker     ret_len = ((ret_bits & 0xffff) + 7) / 8;
89*4d7e907cSAndroid Build Coastguard Worker     buf_len = lab_len + ctx_len + 4;
90*4d7e907cSAndroid Build Coastguard Worker 
91*4d7e907cSAndroid Build Coastguard Worker     memset(ret, 0, ret_len);
92*4d7e907cSAndroid Build Coastguard Worker 
93*4d7e907cSAndroid Build Coastguard Worker     n = (ret_bits + h - 1) / h;
94*4d7e907cSAndroid Build Coastguard Worker     if (n > ((0x1 << r) - 1)) return -1;
95*4d7e907cSAndroid Build Coastguard Worker 
96*4d7e907cSAndroid Build Coastguard Worker     buf = (uint8_t*)calloc(1, buf_len);
97*4d7e907cSAndroid Build Coastguard Worker     if (buf == NULL) return -1;
98*4d7e907cSAndroid Build Coastguard Worker 
99*4d7e907cSAndroid Build Coastguard Worker     memcpy(buf + 1, label, lab_len);
100*4d7e907cSAndroid Build Coastguard Worker     memcpy(buf + lab_len + 2, context, ctx_len);
101*4d7e907cSAndroid Build Coastguard Worker     put_be16(&buf[buf_len - 2], ret_bits);
102*4d7e907cSAndroid Build Coastguard Worker 
103*4d7e907cSAndroid Build Coastguard Worker     for (i = 0; i < n; i++) {
104*4d7e907cSAndroid Build Coastguard Worker         int res;
105*4d7e907cSAndroid Build Coastguard Worker 
106*4d7e907cSAndroid Build Coastguard Worker         buf[0] = (uint8_t)(i + 1);
107*4d7e907cSAndroid Build Coastguard Worker         res = omac1_aes(ctx, buf, buf_len, ret);
108*4d7e907cSAndroid Build Coastguard Worker         if (res) {
109*4d7e907cSAndroid Build Coastguard Worker             free(buf);
110*4d7e907cSAndroid Build Coastguard Worker             return -1;
111*4d7e907cSAndroid Build Coastguard Worker         }
112*4d7e907cSAndroid Build Coastguard Worker         ret = ret + h / 8;
113*4d7e907cSAndroid Build Coastguard Worker     }
114*4d7e907cSAndroid Build Coastguard Worker     free(buf);
115*4d7e907cSAndroid Build Coastguard Worker     return 0;
116*4d7e907cSAndroid Build Coastguard Worker }
117*4d7e907cSAndroid Build Coastguard Worker 
MacsecPskPlugin()118*4d7e907cSAndroid Build Coastguard Worker MacsecPskPlugin::MacsecPskPlugin() {
119*4d7e907cSAndroid Build Coastguard Worker     // always make sure ckn is 16 bytes, zero padded
120*4d7e907cSAndroid Build Coastguard Worker     CKN_1.resize(16);
121*4d7e907cSAndroid Build Coastguard Worker     CKN_2.resize(16);
122*4d7e907cSAndroid Build Coastguard Worker 
123*4d7e907cSAndroid Build Coastguard Worker     addTestKey(CAK_ID_1, CAK_KEY_1, CKN_1);
124*4d7e907cSAndroid Build Coastguard Worker     addTestKey(CAK_ID_2, CAK_KEY_2, CKN_2);
125*4d7e907cSAndroid Build Coastguard Worker }
126*4d7e907cSAndroid Build Coastguard Worker 
~MacsecPskPlugin()127*4d7e907cSAndroid Build Coastguard Worker MacsecPskPlugin::~MacsecPskPlugin() {
128*4d7e907cSAndroid Build Coastguard Worker     for (auto s : mKeys) {
129*4d7e907cSAndroid Build Coastguard Worker         OPENSSL_cleanse(&s.kekEncCtx, sizeof(AES_KEY));
130*4d7e907cSAndroid Build Coastguard Worker         OPENSSL_cleanse(&s.kekDecCtx, sizeof(AES_KEY));
131*4d7e907cSAndroid Build Coastguard Worker         CMAC_CTX_free(s.ickCtx);
132*4d7e907cSAndroid Build Coastguard Worker         CMAC_CTX_free(s.cakCtx);
133*4d7e907cSAndroid Build Coastguard Worker     }
134*4d7e907cSAndroid Build Coastguard Worker }
135*4d7e907cSAndroid Build Coastguard Worker 
addTestKey(const std::vector<uint8_t> & keyId,const std::vector<uint8_t> & CAK,const std::vector<uint8_t> & CKN)136*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus MacsecPskPlugin::addTestKey(const std::vector<uint8_t>& keyId,
137*4d7e907cSAndroid Build Coastguard Worker                                                const std::vector<uint8_t>& CAK,
138*4d7e907cSAndroid Build Coastguard Worker                                                const std::vector<uint8_t>& CKN) {
139*4d7e907cSAndroid Build Coastguard Worker     if (CAK.size() != 16 && CAK.size() != 32) {
140*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "CAK length must be 16 or 32 bytes");
141*4d7e907cSAndroid Build Coastguard Worker     }
142*4d7e907cSAndroid Build Coastguard Worker 
143*4d7e907cSAndroid Build Coastguard Worker     if (keyId.size() != CAK.size()) {
144*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key ID must be same as CAK length");
145*4d7e907cSAndroid Build Coastguard Worker     }
146*4d7e907cSAndroid Build Coastguard Worker 
147*4d7e907cSAndroid Build Coastguard Worker     std::vector<uint8_t> ckn;
148*4d7e907cSAndroid Build Coastguard Worker     ckn = CKN;
149*4d7e907cSAndroid Build Coastguard Worker     ckn.resize(16);  // make sure it is always zero padded with maximum length of
150*4d7e907cSAndroid Build Coastguard Worker                      // 16 bytes
151*4d7e907cSAndroid Build Coastguard Worker 
152*4d7e907cSAndroid Build Coastguard Worker     AES_KEY kekEncCtx;
153*4d7e907cSAndroid Build Coastguard Worker     AES_KEY kekDecCtx;
154*4d7e907cSAndroid Build Coastguard Worker     CMAC_CTX* ickCtx;
155*4d7e907cSAndroid Build Coastguard Worker     CMAC_CTX* cakCtx;
156*4d7e907cSAndroid Build Coastguard Worker 
157*4d7e907cSAndroid Build Coastguard Worker     // Create the CAK openssl context
158*4d7e907cSAndroid Build Coastguard Worker     cakCtx = CMAC_CTX_new();
159*4d7e907cSAndroid Build Coastguard Worker 
160*4d7e907cSAndroid Build Coastguard Worker     CMAC_Init(cakCtx, CAK.data(), CAK.size(),
161*4d7e907cSAndroid Build Coastguard Worker               CAK.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
162*4d7e907cSAndroid Build Coastguard Worker 
163*4d7e907cSAndroid Build Coastguard Worker     // derive KEK from CAK (ieee802_1x_kek_aes_cmac)
164*4d7e907cSAndroid Build Coastguard Worker     std::vector<uint8_t> kek;
165*4d7e907cSAndroid Build Coastguard Worker     kek.resize(CAK.size());
166*4d7e907cSAndroid Build Coastguard Worker 
167*4d7e907cSAndroid Build Coastguard Worker     aes_kdf(cakCtx, "IEEE8021 KEK", (const uint8_t*)ckn.data(), ckn.size() * 8, 8 * kek.size(),
168*4d7e907cSAndroid Build Coastguard Worker             kek.data());
169*4d7e907cSAndroid Build Coastguard Worker 
170*4d7e907cSAndroid Build Coastguard Worker     AES_set_encrypt_key(kek.data(), kek.size() << 3, &kekEncCtx);
171*4d7e907cSAndroid Build Coastguard Worker     AES_set_decrypt_key(kek.data(), kek.size() << 3, &kekDecCtx);
172*4d7e907cSAndroid Build Coastguard Worker 
173*4d7e907cSAndroid Build Coastguard Worker     // derive ICK from CAK (ieee802_1x_ick_aes_cmac)
174*4d7e907cSAndroid Build Coastguard Worker     std::vector<uint8_t> ick;
175*4d7e907cSAndroid Build Coastguard Worker     ick.resize(CAK.size());
176*4d7e907cSAndroid Build Coastguard Worker 
177*4d7e907cSAndroid Build Coastguard Worker     aes_kdf(cakCtx, "IEEE8021 ICK", (const uint8_t*)CKN.data(), CKN.size() * 8, 8 * ick.size(),
178*4d7e907cSAndroid Build Coastguard Worker             ick.data());
179*4d7e907cSAndroid Build Coastguard Worker 
180*4d7e907cSAndroid Build Coastguard Worker     ickCtx = CMAC_CTX_new();
181*4d7e907cSAndroid Build Coastguard Worker 
182*4d7e907cSAndroid Build Coastguard Worker     CMAC_Init(ickCtx, ick.data(), ick.size(),
183*4d7e907cSAndroid Build Coastguard Worker               ick.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
184*4d7e907cSAndroid Build Coastguard Worker 
185*4d7e907cSAndroid Build Coastguard Worker     mKeys.push_back({keyId, kekEncCtx, kekDecCtx, ickCtx, cakCtx});
186*4d7e907cSAndroid Build Coastguard Worker 
187*4d7e907cSAndroid Build Coastguard Worker     return ok();
188*4d7e907cSAndroid Build Coastguard Worker }
189*4d7e907cSAndroid Build Coastguard Worker 
calcIcv(const std::vector<uint8_t> & keyId,const std::vector<uint8_t> & data,std::vector<uint8_t> * out)190*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus MacsecPskPlugin::calcIcv(const std::vector<uint8_t>& keyId,
191*4d7e907cSAndroid Build Coastguard Worker                                             const std::vector<uint8_t>& data,
192*4d7e907cSAndroid Build Coastguard Worker                                             std::vector<uint8_t>* out) {
193*4d7e907cSAndroid Build Coastguard Worker     CMAC_CTX* ctx = NULL;
194*4d7e907cSAndroid Build Coastguard Worker 
195*4d7e907cSAndroid Build Coastguard Worker     for (auto s : mKeys) {
196*4d7e907cSAndroid Build Coastguard Worker         if (s.keyId == keyId) {
197*4d7e907cSAndroid Build Coastguard Worker             ctx = s.ickCtx;
198*4d7e907cSAndroid Build Coastguard Worker             break;
199*4d7e907cSAndroid Build Coastguard Worker         }
200*4d7e907cSAndroid Build Coastguard Worker     }
201*4d7e907cSAndroid Build Coastguard Worker 
202*4d7e907cSAndroid Build Coastguard Worker     if (ctx == NULL) {
203*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
204*4d7e907cSAndroid Build Coastguard Worker     }
205*4d7e907cSAndroid Build Coastguard Worker 
206*4d7e907cSAndroid Build Coastguard Worker     out->resize(16);
207*4d7e907cSAndroid Build Coastguard Worker     if (omac1_aes(ctx, data.data(), data.size(), out->data()) != 0) {
208*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
209*4d7e907cSAndroid Build Coastguard Worker     }
210*4d7e907cSAndroid Build Coastguard Worker 
211*4d7e907cSAndroid Build Coastguard Worker     return ok();
212*4d7e907cSAndroid Build Coastguard Worker }
213*4d7e907cSAndroid Build Coastguard Worker 
generateSak(const std::vector<uint8_t> & keyId,const std::vector<uint8_t> & data,const int sakLength,std::vector<uint8_t> * out)214*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus MacsecPskPlugin::generateSak(const std::vector<uint8_t>& keyId,
215*4d7e907cSAndroid Build Coastguard Worker                                                 const std::vector<uint8_t>& data,
216*4d7e907cSAndroid Build Coastguard Worker                                                 const int sakLength, std::vector<uint8_t>* out) {
217*4d7e907cSAndroid Build Coastguard Worker     CMAC_CTX* ctx = NULL;
218*4d7e907cSAndroid Build Coastguard Worker 
219*4d7e907cSAndroid Build Coastguard Worker     if ((sakLength != 16) && (sakLength != 32)) {
220*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid SAK length");
221*4d7e907cSAndroid Build Coastguard Worker     }
222*4d7e907cSAndroid Build Coastguard Worker 
223*4d7e907cSAndroid Build Coastguard Worker     if (data.size() < sakLength) {
224*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid data length");
225*4d7e907cSAndroid Build Coastguard Worker     }
226*4d7e907cSAndroid Build Coastguard Worker 
227*4d7e907cSAndroid Build Coastguard Worker     for (auto s : mKeys) {
228*4d7e907cSAndroid Build Coastguard Worker         if (s.keyId == keyId) {
229*4d7e907cSAndroid Build Coastguard Worker             ctx = s.cakCtx;
230*4d7e907cSAndroid Build Coastguard Worker             break;
231*4d7e907cSAndroid Build Coastguard Worker         }
232*4d7e907cSAndroid Build Coastguard Worker     }
233*4d7e907cSAndroid Build Coastguard Worker 
234*4d7e907cSAndroid Build Coastguard Worker     if (ctx == NULL) {
235*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
236*4d7e907cSAndroid Build Coastguard Worker     }
237*4d7e907cSAndroid Build Coastguard Worker 
238*4d7e907cSAndroid Build Coastguard Worker     out->resize(sakLength);
239*4d7e907cSAndroid Build Coastguard Worker 
240*4d7e907cSAndroid Build Coastguard Worker     if (aes_kdf(ctx, "IEEE8021 SAK", data.data(), data.size() * 8, out->size() * 8, out->data()) !=
241*4d7e907cSAndroid Build Coastguard Worker         0) {
242*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
243*4d7e907cSAndroid Build Coastguard Worker     }
244*4d7e907cSAndroid Build Coastguard Worker 
245*4d7e907cSAndroid Build Coastguard Worker     return ok();
246*4d7e907cSAndroid Build Coastguard Worker }
247*4d7e907cSAndroid Build Coastguard Worker 
wrapSak(const std::vector<uint8_t> & keyId,const std::vector<uint8_t> & sak,std::vector<uint8_t> * out)248*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus MacsecPskPlugin::wrapSak(const std::vector<uint8_t>& keyId,
249*4d7e907cSAndroid Build Coastguard Worker                                             const std::vector<uint8_t>& sak,
250*4d7e907cSAndroid Build Coastguard Worker                                             std::vector<uint8_t>* out) {
251*4d7e907cSAndroid Build Coastguard Worker     if (sak.size() == 0 || sak.size() % 8 != 0) {
252*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT,
253*4d7e907cSAndroid Build Coastguard Worker                               "SAK length not multiple of 8 or greater than 0");
254*4d7e907cSAndroid Build Coastguard Worker     }
255*4d7e907cSAndroid Build Coastguard Worker 
256*4d7e907cSAndroid Build Coastguard Worker     AES_KEY* ctx = NULL;
257*4d7e907cSAndroid Build Coastguard Worker 
258*4d7e907cSAndroid Build Coastguard Worker     for (auto s : mKeys) {
259*4d7e907cSAndroid Build Coastguard Worker         if (s.keyId == keyId) {
260*4d7e907cSAndroid Build Coastguard Worker             ctx = &s.kekEncCtx;
261*4d7e907cSAndroid Build Coastguard Worker             break;
262*4d7e907cSAndroid Build Coastguard Worker         }
263*4d7e907cSAndroid Build Coastguard Worker     }
264*4d7e907cSAndroid Build Coastguard Worker 
265*4d7e907cSAndroid Build Coastguard Worker     if (ctx == NULL) {
266*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
267*4d7e907cSAndroid Build Coastguard Worker     }
268*4d7e907cSAndroid Build Coastguard Worker 
269*4d7e907cSAndroid Build Coastguard Worker     out->resize(sak.size() + 8);
270*4d7e907cSAndroid Build Coastguard Worker 
271*4d7e907cSAndroid Build Coastguard Worker     if (AES_wrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
272*4d7e907cSAndroid Build Coastguard Worker         return ok();
273*4d7e907cSAndroid Build Coastguard Worker     }
274*4d7e907cSAndroid Build Coastguard Worker 
275*4d7e907cSAndroid Build Coastguard Worker     return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
276*4d7e907cSAndroid Build Coastguard Worker }
277*4d7e907cSAndroid Build Coastguard Worker 
unwrapSak(const std::vector<uint8_t> & keyId,const std::vector<uint8_t> & sak,std::vector<uint8_t> * out)278*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus MacsecPskPlugin::unwrapSak(const std::vector<uint8_t>& keyId,
279*4d7e907cSAndroid Build Coastguard Worker                                               const std::vector<uint8_t>& sak,
280*4d7e907cSAndroid Build Coastguard Worker                                               std::vector<uint8_t>* out) {
281*4d7e907cSAndroid Build Coastguard Worker     if (sak.size() <= 8 || sak.size() % 8 != 0) {
282*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT,
283*4d7e907cSAndroid Build Coastguard Worker                               "SAK length not multiple of 8 or greater than 0");
284*4d7e907cSAndroid Build Coastguard Worker     }
285*4d7e907cSAndroid Build Coastguard Worker 
286*4d7e907cSAndroid Build Coastguard Worker     AES_KEY* ctx = NULL;
287*4d7e907cSAndroid Build Coastguard Worker 
288*4d7e907cSAndroid Build Coastguard Worker     for (auto s : mKeys) {
289*4d7e907cSAndroid Build Coastguard Worker         if (s.keyId == keyId) {
290*4d7e907cSAndroid Build Coastguard Worker             ctx = &s.kekDecCtx;
291*4d7e907cSAndroid Build Coastguard Worker             break;
292*4d7e907cSAndroid Build Coastguard Worker         }
293*4d7e907cSAndroid Build Coastguard Worker     }
294*4d7e907cSAndroid Build Coastguard Worker 
295*4d7e907cSAndroid Build Coastguard Worker     if (ctx == NULL) {
296*4d7e907cSAndroid Build Coastguard Worker         return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
297*4d7e907cSAndroid Build Coastguard Worker     }
298*4d7e907cSAndroid Build Coastguard Worker 
299*4d7e907cSAndroid Build Coastguard Worker     out->resize(sak.size() - 8);
300*4d7e907cSAndroid Build Coastguard Worker 
301*4d7e907cSAndroid Build Coastguard Worker     if (AES_unwrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
302*4d7e907cSAndroid Build Coastguard Worker         return ok();
303*4d7e907cSAndroid Build Coastguard Worker     }
304*4d7e907cSAndroid Build Coastguard Worker 
305*4d7e907cSAndroid Build Coastguard Worker     return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
306*4d7e907cSAndroid Build Coastguard Worker }
307*4d7e907cSAndroid Build Coastguard Worker 
308*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::macsec
309