blob: e435a3fdec956fed3e4dd011ecae19874a0aff3c [file] [log] [blame]
Andres Moralesac808182015-02-26 14:11:04 -08001/*
2 * Copyright 2015 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 */
Andres Moralesb2abaa82015-03-03 09:09:18 -080016#include <time.h>
17#include <iostream>
18#include <iomanip>
19#include <UniquePtr.h>
Andres Moralesac808182015-02-26 14:11:04 -080020
Andres Moralesb2abaa82015-03-03 09:09:18 -080021#include <keyguard/keyguard.h>
Andres Moralesac808182015-02-26 14:11:04 -080022
23namespace keyguard {
24
Andres Moralesb2abaa82015-03-03 09:09:18 -080025Keyguard::~Keyguard() {
26 if (password_key_.buffer.get()) {
27 memset_s(password_key_.buffer.get(), 0, password_key_.length);
Andres Moralesac808182015-02-26 14:11:04 -080028 }
29}
30
Andres Moralesb2abaa82015-03-03 09:09:18 -080031void Keyguard::Enroll(const EnrollRequest &request, EnrollResponse *response) {
Andres Moralesac808182015-02-26 14:11:04 -080032 if (response == NULL) return;
33
34 SizedBuffer enrolled_password;
Andres Moralesb2abaa82015-03-03 09:09:18 -080035 if (!request.provided_password.buffer.get()) {
36 response->error = KG_ERROR_INVALID;
Andres Moralesac808182015-02-26 14:11:04 -080037 return;
38 }
Andres Moralesb2abaa82015-03-03 09:09:18 -080039
40 size_t salt_length;
41 UniquePtr<uint8_t> salt;
42 GetSalt(&salt, &salt_length);
43
44 size_t signature_length;
45 UniquePtr<uint8_t> signature;
46 ComputePasswordSignature(password_key_.buffer.get(),
47 password_key_.length, request.provided_password.buffer.get(),
48 request.provided_password.length, salt.get(), salt_length, &signature,
49 &signature_length);
50
51 SerializeHandle(salt.get(), salt_length, signature.get(), signature_length, enrolled_password);
Andres Moralesac808182015-02-26 14:11:04 -080052 response->SetEnrolledPasswordHandle(&enrolled_password);
53}
54
Andres Moralesb2abaa82015-03-03 09:09:18 -080055void Keyguard::Verify(const VerifyRequest &request, VerifyResponse *response) {
Andres Moralesac808182015-02-26 14:11:04 -080056 if (response == NULL) return;
57
Andres Moralesb2abaa82015-03-03 09:09:18 -080058 if (!request.provided_password.buffer.get() || !request.password_handle.buffer.get()) {
59 response->error = KG_ERROR_INVALID;
Andres Moralesac808182015-02-26 14:11:04 -080060 return;
61 }
62
Andres Moralesb2abaa82015-03-03 09:09:18 -080063 size_t salt_length, signature_length;
64 uint8_t *salt, *signature;
65 keyguard_error_t error = DeserializeHandle(
66 &request.password_handle, &salt, &salt_length, &signature, &signature_length);
67
68 if (error != KG_ERROR_OK) {
69 response->error = error;
70 return;
71 }
72
73 size_t provided_password_signature_length;
74 UniquePtr<uint8_t> provided_password_signature;
75 ComputePasswordSignature(password_key_.buffer.get(),
76 password_key_.length, request.provided_password.buffer.get(), request.provided_password.length,
77 salt, salt_length, &provided_password_signature, &provided_password_signature_length);
78
79 if (provided_password_signature_length == signature_length &&
80 memcmp_s(signature, provided_password_signature.get(), signature_length) == 0) {
Andres Moralesac808182015-02-26 14:11:04 -080081 // Signature matches
82 SizedBuffer auth_token;
Andres Moralesb2abaa82015-03-03 09:09:18 -080083 MintAuthToken(request.user_id, &auth_token.buffer, &auth_token.length);
Andres Moralesac808182015-02-26 14:11:04 -080084 response->SetVerificationToken(&auth_token);
85 } else {
Andres Moralesb2abaa82015-03-03 09:09:18 -080086 response->error = KG_ERROR_INVALID;
Andres Moralesac808182015-02-26 14:11:04 -080087 }
88}
89
Andres Moralesb2abaa82015-03-03 09:09:18 -080090void Keyguard::MintAuthToken(uint32_t user_id, UniquePtr<uint8_t> *auth_token, size_t *length) {
91 if (auth_token == NULL) return;
92
93 AuthToken *token = new AuthToken;
Andres Moralesac808182015-02-26 14:11:04 -080094 SizedBuffer serialized_auth_token;
95
Andres Moralesb2abaa82015-03-03 09:09:18 -080096 struct timespec time;
97 clock_gettime(CLOCK_MONOTONIC_RAW, &time);
Andres Moralesac808182015-02-26 14:11:04 -080098
Andres Moralesb2abaa82015-03-03 09:09:18 -080099 token->auth_token_size = sizeof(AuthToken) -
100 sizeof(token->auth_token_tag) - sizeof(token->auth_token_size);
101 token->user_id = user_id;
102 token->timestamp = static_cast<uint64_t>(time.tv_sec);
Andres Moralesac808182015-02-26 14:11:04 -0800103
Andres Moralesb2abaa82015-03-03 09:09:18 -0800104 UniquePtr<uint8_t> auth_token_key;
105 size_t key_len;
106 GetAuthTokenKey(&auth_token_key, &key_len);
107
108 size_t hash_len = (size_t)((uint8_t *)&token->hmac_tag - (uint8_t *)token);
Andres Moralesac808182015-02-26 14:11:04 -0800109 size_t signature_len;
Andres Moralesb2abaa82015-03-03 09:09:18 -0800110 UniquePtr<uint8_t> signature;
111 ComputeSignature(auth_token_key.get(), key_len,
112 reinterpret_cast<uint8_t *>(token), hash_len, &signature, &signature_len);
Andres Moralesac808182015-02-26 14:11:04 -0800113
Andres Moralesb2abaa82015-03-03 09:09:18 -0800114 memset(&token->hmac, 0, sizeof(token->hmac));
115
116 memcpy(&token->hmac, signature.get(), signature_len > sizeof(token->hmac)
117 ? sizeof(token->hmac) : signature_len);
Andres Moralesac808182015-02-26 14:11:04 -0800118 if (length != NULL) *length = sizeof(AuthToken);
Andres Moralesb2abaa82015-03-03 09:09:18 -0800119 auth_token->reset(reinterpret_cast<uint8_t *>(token));
Andres Moralesac808182015-02-26 14:11:04 -0800120}
Andres Moralesb2abaa82015-03-03 09:09:18 -0800121
122void Keyguard::SerializeHandle(const uint8_t *salt, size_t salt_length, const uint8_t *signature,
123 size_t signature_length, SizedBuffer &result) {
124 const size_t buffer_len = 2 * sizeof(size_t) + salt_length + signature_length;
125 result.buffer.reset(new uint8_t[buffer_len]);
126 result.length = buffer_len;
127 uint8_t *buffer = result.buffer.get();
128 memcpy(buffer, &salt_length, sizeof(salt_length));
129 buffer += sizeof(salt_length);
130 memcpy(buffer, salt, salt_length);
131 buffer += salt_length;
132 memcpy(buffer, &signature_length, sizeof(signature_length));
133 buffer += sizeof(signature_length);
134 memcpy(buffer, signature, signature_length);
135}
136
137keyguard_error_t Keyguard::DeserializeHandle(const SizedBuffer *handle, uint8_t **salt,
138 size_t *salt_length, uint8_t **password, size_t *password_length) {
139 if (handle && handle->length > (2 * sizeof(size_t))) {
140 int read = 0;
141 uint8_t *buffer = handle->buffer.get();
142 memcpy(salt_length, buffer, sizeof(*salt_length));
143 read += sizeof(*salt_length);
144 if (read + *salt_length < handle->length) {
145 *salt = buffer + read;
146 read += *salt_length;
147 if (read + sizeof(*password_length) < handle->length) {
148 buffer += read;
149 memcpy(password_length, buffer, sizeof(*password_length));
150 *password = buffer + sizeof(*password_length);
151 } else {
152 return KG_ERROR_INVALID;
153 }
154 } else {
155 return KG_ERROR_INVALID;
156 }
157
158 return KG_ERROR_OK;
159 }
160 return KG_ERROR_INVALID;
161}
162
Andres Moralesac808182015-02-26 14:11:04 -0800163}