/* * 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__ */