1 /***************************************************************************
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
8 * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22 * The full GNU General Public License is included in this distribution
23 * in the file called LICENSE.GPL.
25 * Contact Information:
30 * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
37 * * Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * * Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in
41 * the documentation and/or other materials provided with the
43 * * Neither the name of Intel Corporation nor the names of its
44 * contributors may be used to endorse or promote products derived
45 * from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
50 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
51 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 * version: Security.L.1.0.130
62 ***************************************************************************/
65 * OCF drv driver header file for the Intel ICP processor.
71 #include <linux/crypto.h>
72 #include <linux/delay.h>
73 #include <linux/skbuff.h>
75 #include "cryptodev.h"
79 #include "cpa_cy_im.h"
80 #include "cpa_cy_sym.h"
81 #include "cpa_cy_rand.h"
82 #include "cpa_cy_dh.h"
83 #include "cpa_cy_rsa.h"
84 #include "cpa_cy_ln.h"
85 #include "cpa_cy_common.h"
86 #include "cpa_cy_dsa.h"
88 #define NUM_BITS_IN_BYTE (8)
89 #define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
90 #define INVALID_DRIVER_ID (-1)
91 #define RETURN_RAND_NUM_GEN_FAILED (-1)
93 /*This is define means only one operation can be chained to another
94 (resulting in one chain of two operations)*/
95 #define MAX_NUM_OF_CHAINED_OPS (1)
96 /*This is the max block cipher initialisation vector*/
97 #define MAX_IV_LEN_IN_BYTES (20)
98 /*This is used to check whether the OCF to this driver session limit has
100 #define NO_OCF_TO_DRV_MAX_SESSIONS (0)
102 /*OCF values mapped here*/
103 #define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
104 #define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
105 #define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
106 #define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
107 #define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
108 #define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
110 #define OCF_REGISTRATION_STATUS_SUCCESS (0)
111 #define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
112 #define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
113 #define ICP_OCF_DRV_STATUS_SUCCESS (0)
114 #define ICP_OCF_DRV_STATUS_FAIL (1)
116 /*Turn on/off debug options*/
117 #define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
118 #define ICP_OCF_PRINT_KERN_ALERT (1)
119 #define ICP_OCF_PRINT_KERN_ERRS (1)
121 /*DSA Prime Q size in bytes (as defined in the standard) */
122 #define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
124 /*MACRO DEFINITIONS*/
126 #define BITS_TO_BYTES(bytes, bits) \
127 bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
129 #define ICP_CACHE_CREATE(cache_ID, cache_name) \
130 kmem_cache_create(cache_ID, sizeof(cache_name),0, \
131 SLAB_HWCACHE_ALIGN, NULL, NULL);
133 #define ICP_CACHE_NULL_CHECK(slab_zone) \
135 if(NULL == slab_zone){ \
136 icp_ocfDrvFreeCaches(); \
137 EPRINTK("%s() line %d: Not enough memory!\n", \
138 __FUNCTION__, __LINE__); \
143 #define ICP_CACHE_DESTROY(slab_zone) \
145 if(NULL != slab_zone){ \
146 kmem_cache_destroy(slab_zone); \
151 #define ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(alg) \
153 if(OCF_REGISTRATION_STATUS_SUCCESS == \
154 crypto_register(icp_ocfDrvDriverId, \
162 #define ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(alg) \
164 if(OCF_REGISTRATION_STATUS_SUCCESS == \
165 crypto_kregister(icp_ocfDrvDriverId, \
172 #if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
173 #define DPRINTK(args...) \
178 #else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
180 #define DPRINTK(args...)
182 #endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
184 #if ICP_OCF_PRINT_KERN_ALERT == 1
185 #define APRINTK(args...) \
187 printk(KERN_ALERT args); \
190 #else //ICP_OCF_PRINT_KERN_ALERT == 1
192 #define APRINTK(args...)
194 #endif //ICP_OCF_PRINT_KERN_ALERT == 1
196 #if ICP_OCF_PRINT_KERN_ERRS == 1
197 #define EPRINTK(args...) \
199 printk(KERN_ERR args); \
202 #else //ICP_OCF_PRINT_KERN_ERRS == 1
204 #define EPRINTK(args...)
206 #endif //ICP_OCF_PRINT_KERN_ERRS == 1
208 #define IPRINTK(args...) \
210 printk(KERN_INFO args); \
213 /*END OF MACRO DEFINITIONS*/
216 ICP_OCF_DRV_ALG_CIPHER
= 0,
218 } icp_ocf_drv_alg_type_t
;
220 /* These are all defined in icp_common.c */
221 extern atomic_t lac_session_failed_dereg_count
;
222 extern atomic_t icp_ocfDrvIsExiting
;
223 extern atomic_t num_ocf_to_drv_registered_sessions
;
225 /*These are use inputs used in icp_sym.c and icp_common.c
226 They are instantiated in icp_common.c*/
227 extern int max_sessions
;
229 extern int32_t icp_ocfDrvDriverId
;
230 extern struct list_head icp_ocfDrvGlobalSymListHead
;
231 extern struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList
;
232 extern struct workqueue_struct
*icp_ocfDrvFreeLacSessionWorkQ
;
233 extern spinlock_t icp_ocfDrvSymSessInfoListSpinlock
;
234 extern rwlock_t icp_kmem_cache_destroy_alloc_lock
;
236 /*Slab zones for symettric functionality, instantiated in icp_common.c*/
237 extern struct kmem_cache
*drvSessionData_zone
;
238 extern struct kmem_cache
*drvOpData_zone
;
240 /*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
241 extern struct kmem_cache
*drvDH_zone
;
242 extern struct kmem_cache
*drvLnModExp_zone
;
243 extern struct kmem_cache
*drvRSADecrypt_zone
;
244 extern struct kmem_cache
*drvRSAPrivateKey_zone
;
245 extern struct kmem_cache
*drvDSARSSign_zone
;
246 extern struct kmem_cache
*drvDSARSSignKValue_zone
;
247 extern struct kmem_cache
*drvDSAVerify_zone
;
249 /*Slab zones for flatbuffers and bufferlist*/
250 extern struct kmem_cache
*drvFlatBuffer_zone
;
252 #define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
254 struct icp_drvBuffListInfo
{
260 extern struct icp_drvBuffListInfo defBuffListInfo
;
263 * This struct is used to keep a reference to the relevant node in the list
264 * of sessionData structs, to the buffer type required by OCF and to the OCF
265 * provided crp struct that needs to be returned. All this info is needed in
266 * the callback function.
268 * IV can sometimes be stored in non-contiguous memory (e.g. skbuff
269 * linked/frag list, therefore a contiguous memory space for the IV data must be
270 * created and passed to LAC
273 struct icp_drvOpData
{
274 CpaCySymOpData lacOpData
;
275 uint32_t digestSizeInBytes
;
278 uint8_t ivData
[MAX_IV_LEN_IN_BYTES
];
279 uint16_t numBufferListArray
;
280 CpaBufferList srcBuffer
;
281 CpaFlatBuffer bufferListArray
[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
];
282 CpaBoolean verifyResult
;
284 /*Values used to derisk chances of performs being called against
285 deregistered sessions (for which the slab page has been reclaimed)
286 This is not a fix - since page frames are reclaimed from a slab, one cannot
287 rely on that memory not being re-used by another app.*/
289 ICP_SESSION_INITIALISED
= 0x5C5C5C,
290 ICP_SESSION_RUNNING
= 0x005C00,
291 ICP_SESSION_DEREGISTERED
= 0xC5C5C5
295 This is the OCF<->OCF_DRV session object:
297 1.The first member is a listNode. These session objects are added to a linked
298 list in order to make it easier to remove them all at session exit time.
299 2.The second member is used to give the session object state and derisk the
300 possibility of OCF batch calls executing against a deregistered session (as
302 3.The third member is a LAC<->OCF_DRV session handle (initialised with the first
303 perform request for that session).
304 4.The fourth is the LAC session context. All the parameters for this structure
305 are only known when the first perform request for this session occurs. That is
306 why the OCF Tolapai Driver only registers a new LAC session at perform time
308 struct icp_drvSessionData
{
309 struct list_head listNode
;
311 CpaCySymSessionCtx sessHandle
;
312 CpaCySymSessionSetupData lacSessCtx
;
315 /* This struct is required for deferred session
316 deregistration as a work queue function can
317 only have one argument*/
318 struct icp_ocfDrvFreeLacSession
{
319 CpaCySymSessionCtx sessionToDeregister
;
320 struct work_struct work
;
323 int icp_ocfDrvNewSession(device_t dev
, uint32_t * sild
, struct cryptoini
*cri
);
325 int icp_ocfDrvFreeLACSession(device_t dev
, uint64_t sid
);
327 int icp_ocfDrvSymProcess(device_t dev
, struct cryptop
*crp
, int hint
);
329 int icp_ocfDrvPkeProcess(device_t dev
, struct cryptkop
*krp
, int hint
);
331 int icp_ocfDrvReadRandom(void *arg
, uint32_t * buf
, int maxwords
);
333 int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister
);
335 int icp_ocfDrvSkBuffToBufferList(struct sk_buff
*skb
,
336 CpaBufferList
* bufferList
);
338 int icp_ocfDrvBufferListToSkBuff(CpaBufferList
* bufferList
,
339 struct sk_buff
**skb
);
341 void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData
, uint32_t len
,
342 CpaFlatBuffer
* pFlatBuffer
);
344 void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn
, uint32_t length
,
345 CpaBufferList
* pBufferList
);
347 void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList
* pBufferList
,
348 void **ppDataOut
, uint32_t * pLength
);
350 int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers
,
351 struct icp_drvBuffListInfo
*buffListInfo
);
353 uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff
*pSkb
);
355 void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer
* pFlatBuffer
);
357 int icp_ocfDrvAllocMetaData(CpaBufferList
* pBufferList
,
358 const struct icp_drvOpData
*pOpData
);
360 void icp_ocfDrvFreeMetaData(CpaBufferList
* pBufferList
);