229 lines
5 KiB
C
229 lines
5 KiB
C
|
/*
|
||
|
* 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 <linux/init.h>
|
||
|
#include <linux/sched.h>
|
||
|
#include <linux/fs.h>
|
||
|
#include <linux/file.h>
|
||
|
#include <linux/fdtable.h>
|
||
|
#include <linux/miscdevice.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/moduleparam.h>
|
||
|
#include <linux/scatterlist.h>
|
||
|
|
||
|
#include <crypto/sha256.h>
|
||
|
#include <crypto/hmac-sha256.h>
|
||
|
|
||
|
#include "fmp_fips_fops_info.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 <linux/compat.h>
|
||
|
|
||
|
/* 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;
|
||
|
u64 DataUnitSeqNumber;
|
||
|
};
|
||
|
|
||
|
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;
|
||
|
};
|
||
|
|
||
|
#endif
|