/**
* \file cryptoEngine.c
* \brief Crypto wrapper interface of low-lovel implementations.
* \author Sergey Tolochko (s.tolochko@samsung.com)
* \version 0.1
* \date Created Sep 29, 2015
* \par In Samsung Ukraine R&D Center (SURC) under a contract between
* \par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
* \par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
* \par Copyright: (c) Samsung Electronics Co, Ltd 2012. All rights reserved.
**/


#include <stdio.h>
#include <string.h>
#include "CommLayerData.h"
#include "cryptoEngine.h"
#include "keyManager.h"
#include "log.h"

// Low-level crypto API definitions
crypto_t CRYPTO_RSA_new(void);
crypto_t CRYPTO_EC_new(void);

void CRYPTO_RSA_free(crypto_t rsa);
void CRYPTO_EC_free(crypto_t ec);

int32_t CRYPTO_RSA_size(const crypto_t rsa);
int32_t CRYPTO_ECDSA_size(const crypto_t ec);

int32_t CRYPTO_RSA_sign(int32_t hash_id, const uint8_t *hash, uint32_t hashlen, 
                   uint8_t *sig, uint32_t *siglen, crypto_t rsa);
int32_t CRYPTO_RSA_verify(int32_t hash_id, const uint8_t *hash, uint32_t hashlen, 
                     const uint8_t *sig, uint32_t siglen, crypto_t rsa);

int32_t CRYPTO_ECDSA_sign(int32_t hash_id, const uint8_t *hash, uint32_t hashlen, 
                   uint8_t *sig, uint32_t *siglen, crypto_t ec);
int32_t CRYPTO_ECDSA_verify(int32_t hash_id, const uint8_t *hash, uint32_t hashlen, 
                     const uint8_t *sig, uint32_t siglen, crypto_t ec);

int32_t CRYPTO_EC_populate_keys(crypto_t *ec, const uint8_t *pubkeyX, size_t pubkeyXlen, 
                                          const uint8_t *pubkeyY, size_t pubkeyYlen,
                                          const uint8_t *privkey, size_t privkeylen);
int32_t CRYPTO_RSA_populate_keys(crypto_t *rsa, const uint8_t *modulus, size_t moduluslen,
                                         const uint8_t *exponent, size_t exponentlen, 
                                         const uint8_t *pmodulus, size_t pmoduluslen);

int32_t CRYPTO_RSA_generate_key(crypto_t rsa, const struct KeyGenInfo* keyInfo);
int32_t CRYPTO_EC_generate_key(crypto_t ec, const struct KeyGenInfo* keyInfo);

int32_t CRYPTO_RSA_public_encrypt(crypto_t rsa, int32_t len, const uint8_t *from, uint8_t *to, int32_t padding);
int32_t CRYPTO_RSA_public_decrypt(crypto_t rsa, int32_t len, const uint8_t *from, uint8_t *to, int32_t padding);

static CRYPTO_API crypto_rsa = {
    CRYPTO_RSA_new,
    CRYPTO_RSA_free,
    CRYPTO_RSA_generate_key,
    CRYPTO_RSA_size,
    CRYPTO_RSA_sign,
    CRYPTO_RSA_verify,
    CRYPTO_RSA_populate_keys,
    CRYPTO_RSA_public_encrypt,
    CRYPTO_RSA_public_decrypt,
};

static CRYPTO_API crypto_ec = {
    CRYPTO_EC_new,
    CRYPTO_EC_free,
    CRYPTO_EC_generate_key,
    CRYPTO_ECDSA_size,
    CRYPTO_ECDSA_sign,
    CRYPTO_ECDSA_verify,
    CRYPTO_EC_populate_keys,
    NULL,
    NULL,
};

CRYPTO_API CRYPTO_get_api(uint32_t type)
{
    if (type == RSA_KEY)
        return crypto_rsa;
    else if (type == ECC_KEY)
        return crypto_ec;
    else 
        LOGE("Unknown key type: %d", type);
    return crypto_rsa; // default
}
