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,2009 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,2009 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.2-229
62 ***************************************************************************/
65 * OCF driver header file for the Intel ICP processor.
72 #include <cpa_cy_im.h>
73 #include <cpa_cy_sym.h>
74 #include <cpa_cy_rand.h>
75 #include <cpa_cy_dh.h>
76 #include <cpa_cy_rsa.h>
77 #include <cpa_cy_ln.h>
78 #include <cpa_cy_common.h>
79 #include <cpa_cy_dsa.h>
83 #define NUM_BITS_IN_BYTE (8)
84 #define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
85 #define INVALID_DRIVER_ID (-1)
86 #define RETURN_RAND_NUM_GEN_FAILED (-1)
88 /*This is the max block cipher initialisation vector*/
89 #define MAX_IV_LEN_IN_BYTES (20)
90 /*This is used to check whether the OCF to this driver session limit has
92 #define NO_OCF_TO_DRV_MAX_SESSIONS (0)
94 /*OCF values mapped here*/
95 #define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
96 #define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
97 #define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
98 #define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
99 #define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
100 #define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
102 #define OCF_REGISTRATION_STATUS_SUCCESS (0)
103 #define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
104 #define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
105 #define ICP_OCF_DRV_STATUS_SUCCESS (0)
106 #define ICP_OCF_DRV_STATUS_FAIL (1)
108 /*Turn on/off debug options*/
109 #define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
110 #define ICP_OCF_PRINT_KERN_ALERT (1)
111 #define ICP_OCF_PRINT_KERN_ERRS (1)
113 #if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
114 #define DPRINTK(args...) \
119 #else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
121 #define DPRINTK(args...)
123 #endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
125 #if ICP_OCF_PRINT_KERN_ALERT == 1
126 #define APRINTK(args...) \
131 #else //ICP_OCF_PRINT_KERN_ALERT == 1
133 #define APRINTK(args...)
135 #endif //ICP_OCF_PRINT_KERN_ALERT == 1
137 #if ICP_OCF_PRINT_KERN_ERRS == 1
138 #define EPRINTK(args...) \
143 #else //ICP_OCF_PRINT_KERN_ERRS == 1
145 #define EPRINTK(args...)
147 #endif //ICP_OCF_PRINT_KERN_ERRS == 1
149 #define IPRINTK(args...) \
154 /*DSA Prime Q size in bytes (as defined in the standard) */
155 #define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
157 #define BITS_TO_BYTES(bytes, bits) \
158 bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
161 ICP_OCF_DRV_ALG_CIPHER
= 0,
163 } icp_ocf_drv_alg_type_t
;
165 typedef ICP_LIST_HEAD(icp_drvSessionListHead_s
,
166 icp_drvSessionData
) icp_drvSessionListHead_t
;
168 /*Values used to derisk chances of performs being called against
169 deregistered sessions (for which the slab page has been reclaimed)
170 This is not a fix - since page frames are reclaimed from a slab, one cannot
171 rely on that memory not being re-used by another app.*/
173 ICP_SESSION_INITIALISED
= 0x5C5C5C,
174 ICP_SESSION_RUNNING
= 0x005C00,
175 ICP_SESSION_DEREGISTERED
= 0xC5C5C5
178 /* This struct is required for deferred session
179 deregistration as a work queue function can
180 only have one argument*/
181 struct icp_ocfDrvFreeLacSession
{
182 CpaCySymSessionCtx sessionToDeregister
;
187 This is the OCF<->OCF_DRV session object:
190 The first member is a listNode. These session objects are added to a linked
191 list in order to make it easier to remove them all at session exit time.
194 The second member is used to give the session object state and derisk the
195 possibility of OCF batch calls executing against a deregistered session (as
199 The third member is a LAC<->OCF_DRV session handle (initialised with the first
200 perform request for that session).
203 The fourth is the LAC session context. All the parameters for this structure
204 are only known when the first perform request for this session occurs. That is
205 why the OCF EP80579 Driver only registers a new LAC session at perform time
207 struct icp_drvSessionData
{
208 ICP_LIST_ENTRY(icp_drvSessionData
) listNode
;
210 CpaCySymSessionCtx sessHandle
;
211 CpaCySymSessionSetupData lacSessCtx
;
214 /* These are all defined in icp_common.c */
215 extern icp_atomic_t lac_session_failed_dereg_count
;
216 extern icp_atomic_t icp_ocfDrvIsExiting
;
217 extern icp_atomic_t num_ocf_to_drv_registered_sessions
;
219 extern int32_t icp_ocfDrvDriverId
;
221 extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead
;
222 extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList
;
223 extern icp_workqueue
*icp_ocfDrvFreeLacSessionWorkQ
;
224 extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock
;
226 /*Slab zones for symettric functionality, instantiated in icp_common.c*/
227 extern icp_kmem_cache drvSessionData_zone
;
228 extern icp_kmem_cache drvOpData_zone
;
230 /*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
231 extern icp_kmem_cache drvDH_zone
;
232 extern icp_kmem_cache drvLnModExp_zone
;
233 extern icp_kmem_cache drvRSADecrypt_zone
;
234 extern icp_kmem_cache drvRSAPrivateKey_zone
;
235 extern icp_kmem_cache drvDSARSSign_zone
;
236 extern icp_kmem_cache drvDSARSSignKValue_zone
;
237 extern icp_kmem_cache drvDSAVerify_zone
;
239 /* Module parameters defined in icp_cpmmon.c*/
241 /* Module parameters - gives the number of times LAC deregistration shall be
243 extern int num_dereg_retries
;
245 /* Module parameter - gives the delay time in jiffies before a LAC session
246 shall be attempted to be deregistered again */
247 extern int dereg_retry_delay_in_jiffies
;
249 /* Module parameter - gives the maximum number of sessions possible between
250 OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
251 extern int max_sessions
;
253 /*Slab zones for flatbuffers and bufferlist*/
254 extern icp_kmem_cache drvFlatBuffer_zone
;
256 #define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
258 struct icp_drvBuffListInfo
{
265 extern struct icp_drvBuffListInfo defBuffListInfo
;
267 /* This struct is used to keep a reference to the relevant node in the list
268 of sessionData structs, to the buffer type required by OCF and to the OCF
269 provided crp struct that needs to be returned. All this info is needed in
270 the callback function.*/
271 struct icp_drvOpData
{
272 CpaCySymOpData lacOpData
;
273 uint32_t digestSizeInBytes
;
276 uint8_t ivData
[MAX_IV_LEN_IN_BYTES
];
277 uint16_t numBufferListArray
;
278 CpaBufferList srcBuffer
;
279 CpaFlatBuffer bufferListArray
[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
];
280 CpaBoolean verifyResult
;
283 /* Create a new session between OCF and this driver*/
284 int icp_ocfDrvNewSession(icp_device_t dev
, uint32_t * sild
,
285 struct cryptoini
*cri
);
287 /* Free a session between this driver and the Quick Assist Framework*/
288 int icp_ocfDrvFreeLACSession(icp_device_t dev
, uint64_t sid
);
290 /* Defer freeing a Quick Assist session*/
291 void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg
);
293 /* Process OCF cryptographic request for a symmetric algorithm*/
294 int icp_ocfDrvSymProcess(icp_device_t dev
, struct cryptop
*crp
, int hint
);
296 /* Process OCF cryptographic request for an asymmetric algorithm*/
297 int icp_ocfDrvPkeProcess(icp_device_t dev
, struct cryptkop
*krp
, int hint
);
299 /* Populate a buffer with random data*/
300 int icp_ocfDrvReadRandom(void *arg
, uint32_t * buf
, int maxwords
);
302 /* Retry Quick Assist session deregistration*/
303 int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister
);
305 /* Convert an OS scatter gather list to a CPA buffer list*/
306 int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t
* pPacketBuffer
,
307 CpaBufferList
* bufferList
);
309 /* Convert a CPA buffer list to an OS scatter gather list*/
310 int icp_ocfDrvBufferListToPacketBuff(CpaBufferList
* bufferList
,
311 icp_packet_buffer_t
** pPacketBuffer
);
313 /* Get the number of buffers in an OS scatter gather list*/
314 uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t
* pPacketBuffer
);
316 /* Convert a single OS buffer to a CPA Flat Buffer*/
317 void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t
* pPacketBuffer
,
318 CpaFlatBuffer
* pFlatBuffer
);
320 /* Add pointer and length to a CPA Flat Buffer structure*/
321 void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData
, uint32_t len
,
322 CpaFlatBuffer
* pFlatBuffer
);
324 /* Convert pointer and length values to a CPA buffer list*/
325 void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn
, uint32_t length
,
326 CpaBufferList
* pBufferList
);
328 /* Convert a CPA buffer list to pointer and length values*/
329 void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList
* pBufferList
,
330 void **ppDataOut
, uint32_t * pLength
);
332 /* Set the number of flat buffers in bufferlist and the size of memory
333 to allocate for the pPrivateMetaData member of the CpaBufferList.*/
334 int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers
,
335 struct icp_drvBuffListInfo
*buffListInfo
);
337 /* Find pointer position of the digest within an OS scatter gather list*/
338 uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
341 uint32_t digestSizeInBytes
);
343 /*This top level function is used to find a pointer to where a digest is
344 stored/needs to be inserted. */
345 uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData
*drvOpData
,
346 struct cryptodesc
*crp_desc
);
348 /* Free a CPA flat buffer*/
349 void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer
* pFlatBuffer
);
351 /* This function will allocate memory for the pPrivateMetaData
352 member of CpaBufferList. */
353 int icp_ocfDrvAllocMetaData(CpaBufferList
* pBufferList
,
354 struct icp_drvOpData
*pOpData
);
356 /* Free data allocated for the pPrivateMetaData
357 member of CpaBufferList.*/
358 void icp_ocfDrvFreeMetaData(CpaBufferList
* pBufferList
);
360 #define ICP_CACHE_CREATE(cache_ID, cache_name) \
361 icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
362 ICP_KERNEL_CACHE_NOINIT)
364 #define ICP_CACHE_FREE(args...) \
365 icp_kmem_cache_free (args)
367 #define ICP_CACHE_DESTROY(slab_zone)\
369 if(NULL != slab_zone){\
370 icp_kmem_cache_destroy(slab_zone);\