mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-03 12:07:58 +00:00
This adds a new method which allows applications to use mdoc ECDSA authentication instead of mdoc MAC authentication. Additionally, also relax requirements on SessionTranscript so the APIs can be used even when mdoc session encryption isn't being used. Also add new VTS test to check for this. Since this is new API, bump API version to 5 and the Identity Credential feature version to 202301. Bug: 241912421 Test: atest VtsHalIdentityTargetTest Test: atest android.security.identity.cts Change-Id: I4085a89be0382c10f5449e13c6a92a46c74c225d
126 lines
4.2 KiB
C
126 lines
4.2 KiB
C
/*
|
|
* Copyright 2020, 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 <inttypes.h>
|
|
|
|
#include "EicCommon.h"
|
|
#include "EicSession.h"
|
|
|
|
// Global used for assigning ids for session objects.
|
|
//
|
|
static uint32_t gSessionLastIdAssigned = 0;
|
|
|
|
// The current session object or NULL if never initialized or if it has been shut down.
|
|
//
|
|
static EicSession* gSessionCurrent = NULL;
|
|
|
|
EicSession* eicSessionGetForId(uint32_t sessionId) {
|
|
if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) {
|
|
return gSessionCurrent;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool eicSessionInit(EicSession* ctx) {
|
|
eicMemSet(ctx, '\0', sizeof(EicSession));
|
|
|
|
if (!eicNextId(&gSessionLastIdAssigned)) {
|
|
eicDebug("Error getting id for object");
|
|
return false;
|
|
}
|
|
ctx->id = gSessionLastIdAssigned;
|
|
|
|
do {
|
|
if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) {
|
|
eicDebug("Failed generating random challenge");
|
|
return false;
|
|
}
|
|
} while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET);
|
|
|
|
if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) {
|
|
eicDebug("Error creating ephemeral key-pair");
|
|
return false;
|
|
}
|
|
|
|
gSessionCurrent = ctx;
|
|
eicDebug("Initialized session with id %" PRIu32, ctx->id);
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionShutdown(EicSession* ctx) {
|
|
if (ctx->id == 0) {
|
|
eicDebug("Trying to shut down session with id 0");
|
|
return false;
|
|
}
|
|
eicDebug("Shut down session with id %" PRIu32, ctx->id);
|
|
eicMemSet(ctx, '\0', sizeof(EicSession));
|
|
gSessionCurrent = NULL;
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionGetId(EicSession* ctx, uint32_t* outId) {
|
|
*outId = ctx->id;
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) {
|
|
*outAuthChallenge = ctx->authChallenge;
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
|
|
uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) {
|
|
eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE);
|
|
ctx->getEphemeralKeyPairCalled = true;
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionSetReaderEphemeralPublicKey(
|
|
EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) {
|
|
eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE);
|
|
ctx->readerEphemeralPublicKeySize = EIC_P256_PUB_KEY_SIZE;
|
|
return true;
|
|
}
|
|
|
|
bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
|
|
size_t sessionTranscriptSize) {
|
|
// If mdoc session encryption is in use, only accept the
|
|
// SessionTranscript if X and Y from the ephemeral key we created
|
|
// is somewhere in SessionTranscript...
|
|
//
|
|
if (ctx->getEphemeralKeyPairCalled) {
|
|
if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
|
|
EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
|
|
eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
|
|
return false;
|
|
}
|
|
if (eicMemMem(sessionTranscript, sessionTranscriptSize,
|
|
ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
|
|
EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
|
|
eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// To save space we only store the SHA-256 of SessionTranscript
|
|
//
|
|
EicSha256Ctx shaCtx;
|
|
eicOpsSha256Init(&shaCtx);
|
|
eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize);
|
|
eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256);
|
|
return true;
|
|
}
|