diff options
Diffstat (limited to 'identity/aidl/default/libeic/EicSession.c')
-rw-r--r-- | identity/aidl/default/libeic/EicSession.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c new file mode 100644 index 0000000000..d0c7a0d77e --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.c @@ -0,0 +1,120 @@ +/* + * 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); + return true; +} + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) { + eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE); + return true; +} + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize) { + // Only accept the SessionTranscript if X and Y from the ephemeral key + // we created is somewhere in SessionTranscript... + // + 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; +} |