Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93f6cba3 authored by Andres Morales's avatar Andres Morales Committed by Android (Google) Code Review
Browse files

Merge "[gatekeeperd] return brute-force throttling information" into mnc-dev

parents 0ca24ff5 ae242929
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -25,9 +25,12 @@ LOCAL_SHARED_LIBRARIES := \
	libgatekeeper \
	liblog \
	libhardware \
	libbase \
	libutils \
	libcrypto \
	libkeystore_binder
LOCAL_STATIC_LIBRARIES := libscrypt_static
LOCAL_C_INCLUDES := external/scrypt/lib/crypto
include $(BUILD_EXECUTABLE)

include $(call first-makefiles-under,$(LOCAL_PATH))
+40 −12
Original line number Diff line number Diff line
@@ -50,18 +50,25 @@ status_t BnGateKeeperService::onTransact(

            uint8_t *out = NULL;
            uint32_t outSize = 0;
            status_t ret = enroll(uid, currentPasswordHandle, currentPasswordHandleSize,
            int ret = enroll(uid, currentPasswordHandle, currentPasswordHandleSize,
                    currentPassword, currentPasswordSize, desiredPassword,
                    desiredPasswordSize, &out, &outSize);

            reply->writeNoException();
            if (ret == NO_ERROR && outSize > 0 && out != NULL) {
            reply->writeInt32(1);
            if (ret == 0 && outSize > 0 && out != NULL) {
                reply->writeInt32(GATEKEEPER_RESPONSE_OK);
                reply->writeInt32(0);
                reply->writeInt32(outSize);
                reply->writeInt32(outSize);
                void *buf = reply->writeInplace(outSize);
                memcpy(buf, out, outSize);
                free(out);
                delete[] out;
            } else if (ret > 0) {
                reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
                reply->writeInt32(ret);
            } else {
                reply->writeInt32(-1);
                reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
            }
            return NO_ERROR;
        }
@@ -78,10 +85,23 @@ status_t BnGateKeeperService::onTransact(
                static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
            if (!currentPassword) currentPasswordSize = 0;

            status_t ret = verify(uid, (uint8_t *) currentPasswordHandle,
                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize);
            bool request_reenroll = false;
            int ret = verify(uid, (uint8_t *) currentPasswordHandle,
                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize,
                    &request_reenroll);

            reply->writeNoException();
            reply->writeInt32(ret == NO_ERROR ? 1 : 0);
            reply->writeInt32(1);
            if (ret == 0) {
                reply->writeInt32(GATEKEEPER_RESPONSE_OK);
                reply->writeInt32(request_reenroll ? 1 : 0);
                reply->writeInt32(0); // no payload returned from this call
            } else if (ret > 0) {
                reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
                reply->writeInt32(ret);
            } else {
                reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
            }
            return NO_ERROR;
        }
        case VERIFY_CHALLENGE: {
@@ -101,17 +121,25 @@ status_t BnGateKeeperService::onTransact(

            uint8_t *out = NULL;
            uint32_t outSize = 0;
            status_t ret = verifyChallenge(uid, challenge, (uint8_t *) currentPasswordHandle,
            bool request_reenroll = false;
            int ret = verifyChallenge(uid, challenge, (uint8_t *) currentPasswordHandle,
                    currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize,
                    &out, &outSize);
                    &out, &outSize, &request_reenroll);
            reply->writeNoException();
            if (ret == NO_ERROR && outSize > 0 && out != NULL) {
            reply->writeInt32(1);
            if (ret == 0 && outSize > 0 && out != NULL) {
                reply->writeInt32(GATEKEEPER_RESPONSE_OK);
                reply->writeInt32(request_reenroll ? 1 : 0);
                reply->writeInt32(outSize);
                reply->writeInt32(outSize);
                void *buf = reply->writeInplace(outSize);
                memcpy(buf, out, outSize);
                free(out);
                delete[] out;
            } else if (ret > 0) {
                reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
                reply->writeInt32(ret);
            } else {
                reply->writeInt32(-1);
                reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
            }
            return NO_ERROR;
        }
+27 −8
Original line number Diff line number Diff line
@@ -35,6 +35,12 @@ public:
        CLEAR_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 4,
    };

    enum {
        GATEKEEPER_RESPONSE_OK = 0,
        GATEKEEPER_RESPONSE_RETRY = 1,
        GATEKEEPER_RESPONSE_ERROR = -1,
    };

    // DECLARE_META_INTERFACE - C++ client interface not needed
    static const android::String16 descriptor;
    virtual const android::String16& getInterfaceDescriptor() const;
@@ -43,8 +49,13 @@ public:

    /**
     * Enrolls a password with the GateKeeper. Returns 0 on success, negative on failure.
     * Returns:
     * - 0 on success
     * - A timestamp T > 0 if the call has failed due to throttling and should not
     *   be reattempted until T milliseconds have elapsed
     * - -1 on failure
     */
    virtual status_t enroll(uint32_t uid,
    virtual int enroll(uint32_t uid,
            const uint8_t *current_password_handle, uint32_t current_password_handle_length,
            const uint8_t *current_password, uint32_t current_password_length,
            const uint8_t *desired_password, uint32_t desired_password_length,
@@ -52,21 +63,29 @@ public:

    /**
     * Verifies a password previously enrolled with the GateKeeper.
     * Returns 0 on success, negative on failure.
     * Returns:
     * - 0 on success
     * - A timestamp T > 0 if the call has failed due to throttling and should not
     *   be reattempted until T milliseconds have elapsed
     * - -1 on failure
     */
    virtual status_t verify(uint32_t uid, const uint8_t *enrolled_password_handle,
    virtual int verify(uint32_t uid, const uint8_t *enrolled_password_handle,
            uint32_t enrolled_password_handle_length,
            const uint8_t *provided_password, uint32_t provided_password_length) = 0;
            const uint8_t *provided_password, uint32_t provided_password_length,
            bool *request_reenroll) = 0;

    /**
     * Verifies a password previously enrolled with the GateKeeper.
     * Returns 0 on success, negative on failure.
     * Returns:
     * - 0 on success
     * - A timestamp T > 0 if the call has failed due to throttling and should not
     *   be reattempted until T milliseconds have elapsed
     * - -1 on failure
     */
    virtual status_t verifyChallenge(uint32_t uid, uint64_t challenge,
    virtual int verifyChallenge(uint32_t uid, uint64_t challenge,
            const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
            const uint8_t *provided_password, uint32_t provided_password_length,
            uint8_t **auth_token, uint32_t *auth_token_length) = 0;

            uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll) = 0;
    /**
     * Returns the secure user ID for the provided android user
     */
+127 −0
Original line number Diff line number Diff line
/*
 * Copyright 2015 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.
 *
 */

#ifndef SOFT_GATEKEEPER_H_
#define SOFT_GATEKEEPER_H_

extern "C" {
#include <openssl/rand.h>
#include <crypto_scrypt.h>
}

#include <UniquePtr.h>
#include <gatekeeper/gatekeeper.h>
#include <iostream>
#include <unordered_map>

namespace gatekeeper {


class SoftGateKeeper : public GateKeeper {
public:
    static const uint32_t SIGNATURE_LENGTH_BYTES = 32;

    // scrypt params
    static const uint64_t N = 16384;
    static const uint32_t r = 8;
    static const uint32_t p = 1;

    static const int MAX_UINT_32_CHARS = 11;

    SoftGateKeeper() {
        key_.reset(new uint8_t[SIGNATURE_LENGTH_BYTES]);
        memset(key_.get(), 0, SIGNATURE_LENGTH_BYTES);
    }

    virtual ~SoftGateKeeper() {
    }

    virtual bool GetAuthTokenKey(const uint8_t **auth_token_key,
            uint32_t *length) const {
        if (auth_token_key == NULL || length == NULL) return false;
        *auth_token_key = const_cast<const uint8_t *>(key_.get());
        *length = SIGNATURE_LENGTH_BYTES;
        return true;
    }

    virtual void GetPasswordKey(const uint8_t **password_key, uint32_t *length) {
        if (password_key == NULL || length == NULL) return;
        *password_key = const_cast<const uint8_t *>(key_.get());
        *length = SIGNATURE_LENGTH_BYTES;
    }

    virtual void ComputePasswordSignature(uint8_t *signature, uint32_t signature_length,
            const uint8_t *, uint32_t, const uint8_t *password,
            uint32_t password_length, salt_t salt) const {
        if (signature == NULL) return;
        crypto_scrypt(password, password_length, reinterpret_cast<uint8_t *>(&salt),
                sizeof(salt), N, r, p, signature, signature_length);
    }

    virtual void GetRandom(void *random, uint32_t requested_length) const {
        if (random == NULL) return;
        RAND_pseudo_bytes((uint8_t *) random, requested_length);
    }

    virtual void ComputeSignature(uint8_t *signature, uint32_t signature_length,
            const uint8_t *, uint32_t, const uint8_t *, const uint32_t) const {
        if (signature == NULL) return;
        memset(signature, 0, signature_length);
    }

    virtual uint64_t GetMillisecondsSinceBoot() const {
        struct timespec time;
        int res = clock_gettime(CLOCK_BOOTTIME, &time);
        if (res < 0) return 0;
        return (time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000);
    }

    virtual bool IsHardwareBacked() const {
        return false;
    }

    virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t *record) {
        failure_record_t *stored = &failure_map_[uid];
        if (user_id != stored->secure_user_id) {
            stored->secure_user_id = user_id;
            stored->last_checked_timestamp = 0;
            stored->failure_counter = 0;
        }
        memcpy(record, stored, sizeof(*record));
        return true;
    }

    virtual void ClearFailureRecord(uint32_t uid, secure_id_t user_id) {
        failure_record_t *stored = &failure_map_[uid];
        stored->secure_user_id = user_id;
        stored->last_checked_timestamp = 0;
        stored->failure_counter = 0;
    }

    virtual bool WriteFailureRecord(uint32_t uid, failure_record_t *record) {
        failure_map_[uid] = *record;
        return true;
    }

private:
    UniquePtr<uint8_t> key_;
    std::unordered_map<uint32_t, failure_record_t> failure_map_;
};
}

#endif // SOFT_GATEKEEPER_H_
+16 −6
Original line number Diff line number Diff line
@@ -13,8 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <gatekeeper/soft_gatekeeper.h>

#include "SoftGateKeeper.h"
#include "SoftGateKeeperDevice.h"

namespace android {
@@ -58,8 +57,11 @@ int SoftGateKeeperDevice::enroll(uint32_t uid,

    impl_->Enroll(request, &response);

    if (response.error != ERROR_NONE)
    if (response.error == ERROR_RETRY) {
        return response.retry_timeout;
    } else if (response.error != ERROR_NONE) {
        return -EINVAL;
    }

    *enrolled_password_handle = response.enrolled_password_handle.buffer.release();
    *enrolled_password_handle_length = response.enrolled_password_handle.length;
@@ -69,7 +71,8 @@ int SoftGateKeeperDevice::enroll(uint32_t uid,
int SoftGateKeeperDevice::verify(uint32_t uid,
        uint64_t challenge, const uint8_t *enrolled_password_handle,
        uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
        uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length) {
        uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
        bool *request_reenroll) {

    if (enrolled_password_handle == NULL ||
            provided_password == NULL) {
@@ -87,14 +90,21 @@ int SoftGateKeeperDevice::verify(uint32_t uid,

    impl_->Verify(request, &response);

    if (response.error != ERROR_NONE)
    if (response.error == ERROR_RETRY) {
        return response.retry_timeout;
    } else if (response.error != ERROR_NONE) {
        return -EINVAL;
    }

    if (auth_token != NULL && auth_token_length != NULL) {
       *auth_token = response.auth_token.buffer.release();
       *auth_token_length = response.auth_token.length;
    }

    if (request_reenroll != NULL) {
        *request_reenroll = response.request_reenroll;
    }

    return 0;
}
} // namespace android
Loading