/* * Exynos FMP device header for FIPS * * Copyright (C) 2015 Samsung Electronics Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #ifndef __FMP_FIPS_INFO_H__ #define __FMP_FIPS_INFO_H__ #include #include #include #include #include #include #include #include #include #include "fmp_fips_fops_info.h" #include "sha256.h" #include "hmac-sha256.h" #define BYPASS_MODE 0 #define CBC_MODE 1 #define XTS_MODE 2 struct fcrypt { struct list_head list; struct mutex sem; }; /* kernel-internal extension to struct crypt_op */ struct kernel_crypt_op { struct crypt_op cop; int ivlen; __u8 iv[EALG_MAX_BLOCK_LEN]; int digestsize; uint8_t hash_output[AALG_MAX_RESULT_LEN]; struct task_struct *task; struct mm_struct *mm; }; struct todo_list_item { struct list_head __hook; struct kernel_crypt_op kcop; int result; }; struct locked_list { struct list_head list; struct mutex lock; }; struct fmp_fips_info { struct fcrypt fcrypt; struct locked_list free, todo, done; int itemcount; struct work_struct fmptask; wait_queue_head_t user_waiter; struct exynos_fmp *fmp; struct fmp_test_data *data; }; /* compatibility stuff */ #ifdef CONFIG_COMPAT #include /* input of FMPGSESSION */ struct compat_session_op { /* Specify either cipher or mac */ uint32_t cipher; /* cryptodev_crypto_op_t */ uint32_t mac; /* cryptodev_crypto_op_t */ uint32_t keylen; compat_uptr_t key; /* pointer to key data */ uint32_t mackeylen; compat_uptr_t mackey; /* pointer to mac key data */ uint32_t ses; /* session identifier */ }; /* input of FMPCRYPT */ struct compat_crypt_op { uint32_t ses; /* session identifier */ uint16_t op; /* COP_ENCRYPT or COP_DECRYPT */ uint16_t flags; /* see COP_FLAG_* */ uint32_t len; /* length of source data */ compat_uptr_t src; /* source data */ compat_uptr_t dst; /* pointer to output data */ compat_uptr_t mac;/* pointer to output data for hash/MAC operations */ compat_uptr_t iv;/* initialization vector for encryption operations */ __u32 data_unit_len; __u32 data_unit_seqnumber; compat_uptr_t secondLastEncodedData; compat_uptr_t thirdLastEncodedData; }; #define COMPAT_FMPGSESSION _IOWR('c', 200, struct compat_session_op) #define COMPAT_FMPCRYPT _IOWR('c', 203, struct compat_crypt_op) #define COMPAT_FMP_AES_CBC_MCT _IOWR('c', 204, struct compat_crypt_op) #endif /* the maximum of the above */ #define EALG_MAX_BLOCK_LEN 16 struct cipher_data { int init; /* 0 uninitialized */ int blocksize; int aead; int stream; int ivsize; int alignmask; struct { /* block ciphers */ struct crypto_ablkcipher *s; struct ablkcipher_request *request; /* AEAD ciphers */ struct crypto_aead *as; struct aead_request *arequest; struct fmp_fips_result *result; uint8_t iv[EALG_MAX_BLOCK_LEN]; } async; }; struct hash_data { int init; /* 0 uninitialized */ int digestsize; int alignmask; SHA256_CTX *sha; HMAC_SHA256_CTX *hmac; struct { struct crypto_ahash *s; struct fmp_fips_result *result; struct ahash_request *request; } async; }; struct fmp_fips_result { struct completion completion; int err; }; /* other internal structs */ struct csession { struct list_head entry; struct mutex sem; struct cipher_data cdata; struct hash_data hdata; uint32_t sid; uint32_t alignmask; unsigned int array_size; unsigned int used_pages; /* the number of pages that are used */ /* the number of pages marked as writable (first are the readable) */ unsigned int readable_pages; struct page **pages; struct scatterlist *sg; }; struct csession *fmp_get_session_by_sid(struct fcrypt *fcr, uint32_t sid); static inline void fmp_put_session(struct csession *ses_ptr) { mutex_unlock(&ses_ptr->sem); } int adjust_sg_array(struct csession *ses, int pagecount); #define MAX_TAP 8 #define XBUFSIZE 8 #define FIPS_MAX_LEN_KEY 128 #define FIPS_MAX_LEN_IV 32 #define FIPS_MAX_LEN_PCTEXT 512 #define FIPS_MAX_LEN_DIGEST 64 struct cipher_testvec { const char key[FIPS_MAX_LEN_KEY]; const char iv[FIPS_MAX_LEN_IV]; const char input[FIPS_MAX_LEN_PCTEXT]; const char result[FIPS_MAX_LEN_PCTEXT]; unsigned short tap[MAX_TAP]; int np; unsigned char also_non_np; unsigned char klen; unsigned short ilen; unsigned short rlen; }; struct hash_testvec { /* only used with keyed hash algorithms */ const char key[FIPS_MAX_LEN_KEY]; const char plaintext[FIPS_MAX_LEN_PCTEXT]; const char digest[FIPS_MAX_LEN_DIGEST]; unsigned char tap[MAX_TAP]; unsigned short psize; unsigned char np; unsigned char ksize; }; struct cipher_test_suite { struct { const struct cipher_testvec *vecs; unsigned int count; } enc; }; struct hash_test_suite { const struct hash_testvec *vecs; unsigned int count; }; struct exynos_fmp_fips_test_vops { int (*integrity)(HMAC_SHA256_CTX *desc, unsigned long *start_addr); int (*zeroization)(struct fmp_table_setting *table, char *str); int (*hmac_sha256)(char *digest, char *algorithm); int (*aes)(const int mode, char *key, unsigned char klen); }; #endif