blob: 55a9988577f343c6d36e0c87a5b1eb426f2d9fe5 [file] [log] [blame]
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __MSM_CTR_DRBG_H__
#define __MSM_CTR_DRBG_H__
/* This is the module that is actually follows the details of NIST SP
* 800-90 so it can claim to use a FIPS-approved algorithm.
*/
/* Added ctr_drbg_generate_w_data which supplies
* additional input to the generate operation.
*/
#define CTR_DRBG_MAX_REQ_LEN_BITS (1 << 19)
#define CTR_DRBG_SEED_LEN_BITS 256
#define CTR_DRBG_BLOCK_LEN_BITS 128
#define CTR_DRBG_BLOCK_LEN_BYTES (CTR_DRBG_BLOCK_LEN_BITS/8)
#define CTR_DRBG_MAX_RESEED_INTERVAL (1ULL << 48)
#define MSM_AES128_BLOCK_SIZE (16)
#define MSM_ENTROPY_BUFFER_SIZE (16)
#define MSM_NONCE_BUFFER_SIZE (8)
enum ctr_drbg_status_t {
CTR_DRBG_SUCCESS = 0,
CTR_DRBG_NEEDS_RESEED,
CTR_DRBG_INVALID_ARG,
CTR_DRBG_GENERAL_ERROR = 0xFF,
};
union ctr_drbg_seed_t {
uint8_t as_bytes[32];
uint32_t as_words[8];
uint64_t as_64[4];
struct {
uint8_t key[16];
uint8_t V[16];
} key_V;
};
struct msm_ctr_tcrypt_result_s {
struct completion completion;
int err;
};
struct msm_ctr_buffer_s {
unsigned char *virt_addr;
};
struct aes_struct_s {
struct crypto_ablkcipher *tfm;
struct ablkcipher_request *req;
struct msm_ctr_buffer_s input;
struct msm_ctr_buffer_s output;
struct msm_ctr_tcrypt_result_s result;
};
struct ctr_drbg_ctx_s {
unsigned long long reseed_counter; /* starts at 1 as per SP
* 800-90
*/
unsigned long long reseed_interval;
union ctr_drbg_seed_t seed;
struct aes_struct_s aes_ctx;
struct aes_struct_s df_aes_ctx;
uint8_t prev_drn[MSM_AES128_BLOCK_SIZE];
uint8_t continuous_test_started;
};
enum ctr_drbg_status_t ctr_drbg_instantiate(struct ctr_drbg_ctx_s *ctx,
const uint8_t *entropy,
size_t entropy_len_bits,
const uint8_t *nonce,
size_t nonce_len_bits,
unsigned long long reseed_interval);
enum ctr_drbg_status_t ctr_drbg_reseed(struct ctr_drbg_ctx_s *ctx,
const void *entropy,
size_t entropy_len);
enum ctr_drbg_status_t ctr_drbg_generate_w_data(struct ctr_drbg_ctx_s *ctx,
void *additional_input,
size_t additional_input_len_bits,
void *buffer,
size_t len_bits);
enum ctr_drbg_status_t ctr_drbg_generate(struct ctr_drbg_ctx_s *ctx,
void *buffer,
size_t len);
void ctr_drbg_uninstantiate(struct ctr_drbg_ctx_s *ctx);
enum ctr_drbg_status_t block_cipher_df(struct ctr_drbg_ctx_s *ctx,
const uint8_t *input,
uint32_t input_size,
uint8_t *output,
uint32_t output_size
);
void ctr_aes_deinit(struct ctr_drbg_ctx_s *ctx);
#endif /* __MSM_CTR_DRBG_H__ */