#include "crypto_module.h"

#include <qsee_hash.h>
#include <qsee_fs.h>
#include <qsee_kdf.h>
#include <qsee_prng.h>
#include <qsee_core.h>
#include <stdio.h>
#include <unistd.h>


#if AP_ID_SIZE * 2 != SHA256_DIGEST_SIZE
#   error Bad apId derivation algorithm
#endif

CRYPTO_STATUS  crypto_gen_random( uint8_t *out, uint32_t size ) {
    int32_t  res;
    uint8_t  *out_ptr = out;

    while ( size != 0 ) {
        res = qsee_prng_getdata( out_ptr, (size < QSEE_MAX_PRNG) ? size : QSEE_MAX_PRNG );
        if ( res <= 0 ) {
            LOGE( "qsee_prng_getdata failed with code %d", res );
            return CRYPTO_STATUS_FAILED;
        }

        out_ptr += res;
        size -= res;
    }

    return CRYPTO_STATUS_SUCCESS;
}


CRYPTO_STATUS  crypto_get_tz_encryption_key( uint8_t out[AES_256_KEY_SIZE] ) {
    int res;
    uint8_t keyLabel[] = "OTP encryption key";
    uint8_t keySalt[] = "SSPM TZ KDF";

    res = qsee_kdf( NULL, AES_256_KEY_SIZE,
                    keyLabel, sizeof(keyLabel) - 1,
                    keySalt, sizeof(keySalt) - 1,
                    out, AES_256_KEY_SIZE);
    if( 0 != res ) {
        LOGE( "qsee_kdf failed with code %d", res );
        return CRYPTO_STATUS_FAILED;
    }

    return CRYPTO_STATUS_SUCCESS;
}


CRYPTO_STATUS  crypto_get_apId( uint8_t apId[AP_ID_SIZE] ) {
    CRYPTO_STATUS   status;
    uint32_t    i;
    uint8_t     hashed[SHA256_DIGEST_SIZE];
    uint8_t     buffer[1024];
    size_t      bufferSize = sizeof(buffer);

#ifdef USE_QSEE_API_DEVICE_UUID
    if (qsee_get_device_uuid(buffer, &bufferSize) != 0) {
        bufferSize = sizeof(buffer);
        crypto_gen_random(buffer, bufferSize);
    }
#else
    crypto_gen_random(buffer, bufferSize);
#endif

    status = crypto_sha256( hashed, buffer, bufferSize, NULL );

    for ( i = 0; i < AP_ID_SIZE; ++i ) {
        apId[i] = hashed[i] ^ hashed[AP_ID_SIZE + i];
    }

    return status;
}

