• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <inttypes.h>
18 
19 #include "EicCommon.h"
20 #include "EicSession.h"
21 
22 // Global used for assigning ids for session objects.
23 //
24 static uint32_t gSessionLastIdAssigned = 0;
25 
26 // The current session object or NULL if never initialized or if it has been shut down.
27 //
28 static EicSession* gSessionCurrent = NULL;
29 
eicSessionGetForId(uint32_t sessionId)30 EicSession* eicSessionGetForId(uint32_t sessionId) {
31     if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) {
32         return gSessionCurrent;
33     }
34     return NULL;
35 }
36 
eicSessionInit(EicSession * ctx)37 bool eicSessionInit(EicSession* ctx) {
38     eicMemSet(ctx, '\0', sizeof(EicSession));
39 
40     if (!eicNextId(&gSessionLastIdAssigned)) {
41         eicDebug("Error getting id for object");
42         return false;
43     }
44     ctx->id = gSessionLastIdAssigned;
45 
46     do {
47         if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) {
48             eicDebug("Failed generating random challenge");
49             return false;
50         }
51     } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET);
52 
53     if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) {
54         eicDebug("Error creating ephemeral key-pair");
55         return false;
56     }
57 
58     gSessionCurrent = ctx;
59     eicDebug("Initialized session with id %" PRIu32, ctx->id);
60     return true;
61 }
62 
eicSessionShutdown(EicSession * ctx)63 bool eicSessionShutdown(EicSession* ctx) {
64     if (ctx->id == 0) {
65         eicDebug("Trying to shut down session with id 0");
66         return false;
67     }
68     eicDebug("Shut down session with id %" PRIu32, ctx->id);
69     eicMemSet(ctx, '\0', sizeof(EicSession));
70     gSessionCurrent = NULL;
71     return true;
72 }
73 
eicSessionGetId(EicSession * ctx,uint32_t * outId)74 bool eicSessionGetId(EicSession* ctx, uint32_t* outId) {
75     *outId = ctx->id;
76     return true;
77 }
78 
eicSessionGetAuthChallenge(EicSession * ctx,uint64_t * outAuthChallenge)79 bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) {
80     *outAuthChallenge = ctx->authChallenge;
81     return true;
82 }
83 
eicSessionGetEphemeralKeyPair(EicSession * ctx,uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE])84 bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
85                                    uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) {
86     eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE);
87     return true;
88 }
89 
eicSessionSetReaderEphemeralPublicKey(EicSession * ctx,const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE])90 bool eicSessionSetReaderEphemeralPublicKey(
91         EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) {
92     eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE);
93     return true;
94 }
95 
eicSessionSetSessionTranscript(EicSession * ctx,const uint8_t * sessionTranscript,size_t sessionTranscriptSize)96 bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
97                                     size_t sessionTranscriptSize) {
98     // Only accept the SessionTranscript if X and Y from the ephemeral key
99     // we created is somewhere in SessionTranscript...
100     //
101     if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
102                   EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
103         eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
104         return false;
105     }
106     if (eicMemMem(sessionTranscript, sessionTranscriptSize,
107                   ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
108                   EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
109         eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
110         return false;
111     }
112 
113     // To save space we only store the SHA-256 of SessionTranscript
114     //
115     EicSha256Ctx shaCtx;
116     eicOpsSha256Init(&shaCtx);
117     eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize);
118     eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256);
119     return true;
120 }
121