Root/target/linux/generic-2.6/files/crypto/ocf/ep80579/icp_asym.c

1/***************************************************************************
2 *
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.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
9 *
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.
13 *
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.
18 *
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.
24 *
25 * Contact Information:
26 * Intel Corporation
27 *
28 * BSD LICENSE
29 *
30 * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 *
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
42 * distribution.
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.
46 *
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.
58 *
59 *
60 * version: Security.L.1.0.130
61 *
62 ***************************************************************************/
63
64#include "icp_ocf.h"
65
66/*The following define values (containing the word 'INDEX') are used to find
67the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
68These values were found through analysis of the OCF OpenSSL patch. If the
69calling program uses different input buffer positions, these defines will have
70to be changed.*/
71
72/*DIFFIE HELLMAN buffer index values*/
73#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
74#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
75#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
76#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
77
78/*MOD EXP buffer index values*/
79#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
80#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
81#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
82#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
83
84#define SINGLE_BYTE_VALUE (4)
85
86/*MOD EXP CRT buffer index values*/
87#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
88#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
89#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
90#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
91#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
92#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
93#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
94
95/*DSA sign buffer index values*/
96#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
97#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
98#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
99#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
100#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
101#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
102#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
103
104/*DSA verify buffer index values*/
105#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
106#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
107#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
108#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
109#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
110#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
111#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
112
113/*DSA sign prime Q vs random number K size check values*/
114#define DONT_RUN_LESS_THAN_CHECK (0)
115#define FAIL_A_IS_GREATER_THAN_B (1)
116#define FAIL_A_IS_EQUAL_TO_B (1)
117#define SUCCESS_A_IS_LESS_THAN_B (0)
118#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
119
120/* We need to set a cryptokp success value just in case it is set or allocated
121   and not set to zero outside of this module */
122#define CRYPTO_OP_SUCCESS (0)
123
124static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
125
126static int icp_ocfDrvModExp(struct cryptkop *krp);
127
128static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
129
130static int
131icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
132
133static int icp_ocfDrvDsaSign(struct cryptkop *krp);
134
135static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
136
137static void
138icp_ocfDrvDhP1CallBack(void *callbackTag,
139               CpaStatus status,
140               void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
141
142static void
143icp_ocfDrvModExpCallBack(void *callbackTag,
144             CpaStatus status,
145             void *pOpData, CpaFlatBuffer * pResult);
146
147static void
148icp_ocfDrvModExpCRTCallBack(void *callbackTag,
149                CpaStatus status,
150                void *pOpData, CpaFlatBuffer * pOutputData);
151
152static void
153icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
154                CpaStatus status,
155                void *pOpData, CpaBoolean verifyStatus);
156
157static void
158icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
159                CpaStatus status,
160                void *pOpData,
161                CpaBoolean protocolStatus,
162                CpaFlatBuffer * pR, CpaFlatBuffer * pS);
163
164/* Name : icp_ocfDrvPkeProcess
165 *
166 * Description : This function will choose which PKE process to follow
167 * based on the input arguments
168 */
169int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint)
170{
171    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
172
173    if (NULL == krp) {
174        DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
175            __FUNCTION__, krp);
176        return EINVAL;
177    }
178
179    if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
180        krp->krp_status = ECANCELED;
181        return ECANCELED;
182    }
183
184    switch (krp->krp_op) {
185    case CRK_DH_COMPUTE_KEY:
186        DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
187        lacStatus = icp_ocfDrvDHComputeKey(krp);
188        if (CPA_STATUS_SUCCESS != lacStatus) {
189            EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
190                "(%d).\n", __FUNCTION__, lacStatus);
191            krp->krp_status = ECANCELED;
192            return ECANCELED;
193        }
194
195        break;
196
197    case CRK_MOD_EXP:
198        DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
199        lacStatus = icp_ocfDrvModExp(krp);
200        if (CPA_STATUS_SUCCESS != lacStatus) {
201            EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
202                __FUNCTION__, lacStatus);
203            krp->krp_status = ECANCELED;
204            return ECANCELED;
205        }
206
207        break;
208
209    case CRK_MOD_EXP_CRT:
210        DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
211        lacStatus = icp_ocfDrvModExpCRT(krp);
212        if (CPA_STATUS_SUCCESS != lacStatus) {
213            EPRINTK("%s(): icp_ocfDrvModExpCRT "
214                "failed (%d).\n", __FUNCTION__, lacStatus);
215            krp->krp_status = ECANCELED;
216            return ECANCELED;
217        }
218
219        break;
220
221    case CRK_DSA_SIGN:
222        DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
223        lacStatus = icp_ocfDrvDsaSign(krp);
224        if (CPA_STATUS_SUCCESS != lacStatus) {
225            EPRINTK("%s(): icp_ocfDrvDsaSign "
226                "failed (%d).\n", __FUNCTION__, lacStatus);
227            krp->krp_status = ECANCELED;
228            return ECANCELED;
229        }
230
231        break;
232
233    case CRK_DSA_VERIFY:
234        DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
235        lacStatus = icp_ocfDrvDsaVerify(krp);
236        if (CPA_STATUS_SUCCESS != lacStatus) {
237            EPRINTK("%s(): icp_ocfDrvDsaVerify "
238                "failed (%d).\n", __FUNCTION__, lacStatus);
239            krp->krp_status = ECANCELED;
240            return ECANCELED;
241        }
242
243        break;
244
245    default:
246        EPRINTK("%s(): Asymettric function not "
247            "supported (%d).\n", __FUNCTION__, krp->krp_op);
248        krp->krp_status = EOPNOTSUPP;
249        return EOPNOTSUPP;
250    }
251
252    return ICP_OCF_DRV_STATUS_SUCCESS;
253}
254
255/* Name : icp_ocfDrvSwapBytes
256 *
257 * Description : This function is used to swap the byte order of a buffer.
258 * It has been seen that in general we are passed little endian byte order
259 * buffers, but LAC only accepts big endian byte order buffers.
260 */
261static void inline
262icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
263{
264
265    int i;
266    u_int8_t *end_ptr;
267    u_int8_t hold_val;
268
269    end_ptr = num + (buff_len_bytes - 1);
270    buff_len_bytes = buff_len_bytes >> 1;
271    for (i = 0; i < buff_len_bytes; i++) {
272        hold_val = *num;
273        *num = *end_ptr;
274        num++;
275        *end_ptr = hold_val;
276        end_ptr--;
277    }
278}
279
280/* Name : icp_ocfDrvDHComputeKey
281 *
282 * Description : This function will map Diffie Hellman calls from OCF
283 * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
284 * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
285 * break down to a modular exponentiation.
286 */
287static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
288{
289    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
290    void *callbackTag = NULL;
291    CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
292    CpaFlatBuffer *pLocalOctetStringPV = NULL;
293    uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
294
295    /* Input checks - check prime is a multiple of 8 bits to allow for
296       allocation later */
297    dh_prime_len_bits =
298        (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
299
300    /* LAC can reject prime lengths based on prime key sizes, we just
301       need to make sure we can allocate space for the base and
302       exponent buffers correctly */
303    if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
304        APRINTK("%s(): Warning Prime number buffer size is not a "
305            "multiple of 8 bits\n", __FUNCTION__);
306    }
307
308    /* Result storage space should be the same size as the prime as this
309       value can take up the same amount of storage space */
310    if (dh_prime_len_bits !=
311        krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
312        DPRINTK("%s(): Return Buffer must be the same size "
313            "as the Prime buffer\n", __FUNCTION__);
314        krp->krp_status = EINVAL;
315        return EINVAL;
316    }
317    /* Switch to size in bytes */
318    BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
319
320    callbackTag = krp;
321
322    pPhase1OpData = kmem_cache_zalloc(drvDH_zone, GFP_KERNEL);
323    if (NULL == pPhase1OpData) {
324        APRINTK("%s():Failed to get memory for key gen data\n",
325            __FUNCTION__);
326        krp->krp_status = ENOMEM;
327        return ENOMEM;
328    }
329
330    pLocalOctetStringPV = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
331    if (NULL == pLocalOctetStringPV) {
332        APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
333            __FUNCTION__);
334        kmem_cache_free(drvDH_zone, pPhase1OpData);
335        krp->krp_status = ENOMEM;
336        return ENOMEM;
337    }
338
339    /* Link parameters */
340    pPhase1OpData->primeP.pData =
341        krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
342
343    pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
344
345    icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
346
347    pPhase1OpData->baseG.pData =
348        krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
349
350    BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
351              krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
352
353    icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
354                pPhase1OpData->baseG.dataLenInBytes);
355
356    pPhase1OpData->privateValueX.pData =
357        krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
358
359    BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
360              krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
361              crp_nbits);
362
363    icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
364                pPhase1OpData->privateValueX.dataLenInBytes);
365
366    /* Output parameters */
367    pLocalOctetStringPV->pData =
368        krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
369
370    BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
371              krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
372
373    lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
374                    icp_ocfDrvDhP1CallBack,
375                    callbackTag, pPhase1OpData,
376                    pLocalOctetStringPV);
377
378    if (CPA_STATUS_SUCCESS != lacStatus) {
379        EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
380            __FUNCTION__, lacStatus);
381        icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
382        kmem_cache_free(drvDH_zone, pPhase1OpData);
383    }
384
385    return lacStatus;
386}
387
388/* Name : icp_ocfDrvModExp
389 *
390 * Description : This function will map ordinary Modular Exponentiation calls
391 * from OCF to the LAC API.
392 *
393 */
394static int icp_ocfDrvModExp(struct cryptkop *krp)
395{
396    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
397    void *callbackTag = NULL;
398    CpaCyLnModExpOpData *pModExpOpData = NULL;
399    CpaFlatBuffer *pResult = NULL;
400
401    if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
402         NUM_BITS_IN_BYTE) != 0) {
403        DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
404            "multiple of 8 bits\n", __FUNCTION__,
405            krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
406            crp_nbits);
407    }
408
409    /* Result storage space should be the same size as the prime as this
410       value can take up the same amount of storage space */
411    if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
412        krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
413        APRINTK("%s(): Return Buffer size must be the same or"
414            " greater than the Modulus buffer\n", __FUNCTION__);
415        krp->krp_status = EINVAL;
416        return EINVAL;
417    }
418
419    callbackTag = krp;
420
421    pModExpOpData = kmem_cache_zalloc(drvLnModExp_zone, GFP_KERNEL);
422    if (NULL == pModExpOpData) {
423        APRINTK("%s():Failed to get memory for key gen data\n",
424            __FUNCTION__);
425        krp->krp_status = ENOMEM;
426        return ENOMEM;
427    }
428
429    pResult = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
430    if (NULL == pResult) {
431        APRINTK("%s():Failed to get memory for ModExp result\n",
432            __FUNCTION__);
433        kmem_cache_free(drvLnModExp_zone, pModExpOpData);
434        krp->krp_status = ENOMEM;
435        return ENOMEM;
436    }
437
438    /* Link parameters */
439    pModExpOpData->modulus.pData =
440        krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
441    BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
442              krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
443              crp_nbits);
444
445    icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
446                pModExpOpData->modulus.dataLenInBytes);
447
448    /*OCF patch to Openswan Pluto regularly sends the base value as 2
449       bits in size. In this case, it has been found it is better to
450       use the base size memory space as the input buffer (if the number
451       is in bits is less than a byte, the number of bits is the input
452       value) */
453    if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits <
454        NUM_BITS_IN_BYTE) {
455        DPRINTK("%s : base is small (%d)\n", __FUNCTION__, krp->
456            krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
457        pModExpOpData->base.dataLenInBytes = SINGLE_BYTE_VALUE;
458        pModExpOpData->base.pData =
459            (uint8_t *) & (krp->
460                   krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
461                   crp_nbits);
462        *((uint32_t *) pModExpOpData->base.pData) =
463            htonl(*((uint32_t *) pModExpOpData->base.pData));
464
465    } else {
466
467        DPRINTK("%s : base is big (%d)\n", __FUNCTION__, krp->
468            krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
469        pModExpOpData->base.pData =
470            krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
471        BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
472                  krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
473                  crp_nbits);
474        icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
475                    pModExpOpData->base.dataLenInBytes);
476    }
477
478    pModExpOpData->exponent.pData =
479        krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
480    BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
481              krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
482              crp_nbits);
483
484    icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
485                pModExpOpData->exponent.dataLenInBytes);
486    /* Output parameters */
487    pResult->pData =
488        krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
489        BITS_TO_BYTES(pResult->dataLenInBytes,
490              krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
491              crp_nbits);
492
493    lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
494                  icp_ocfDrvModExpCallBack,
495                  callbackTag, pModExpOpData, pResult);
496
497    if (CPA_STATUS_SUCCESS != lacStatus) {
498        EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
499            __FUNCTION__, lacStatus);
500        krp->krp_status = ECANCELED;
501        icp_ocfDrvFreeFlatBuffer(pResult);
502        kmem_cache_free(drvLnModExp_zone, pModExpOpData);
503    }
504
505    return lacStatus;
506}
507
508/* Name : icp_ocfDrvModExpCRT
509 *
510 * Description : This function will map ordinary Modular Exponentiation Chinese
511 * Remainder Theorem implementaion calls from OCF to the LAC API.
512 *
513 * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
514 * decrypt operation. Therefore P and Q input values must always be prime
515 * numbers. Although basic primality checks are done in LAC, it is up to the
516 * user to do any correct prime number checking before passing the inputs.
517 */
518
519static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
520{
521    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
522    CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
523    void *callbackTag = NULL;
524    CpaFlatBuffer *pOutputData = NULL;
525
526    /*Parameter input checks are all done by LAC, no need to repeat
527       them here. */
528    callbackTag = krp;
529
530    rsaDecryptOpData = kmem_cache_zalloc(drvRSADecrypt_zone, GFP_KERNEL);
531    if (NULL == rsaDecryptOpData) {
532        APRINTK("%s():Failed to get memory"
533            " for MOD EXP CRT Op data struct\n", __FUNCTION__);
534        krp->krp_status = ENOMEM;
535        return ENOMEM;
536    }
537
538    rsaDecryptOpData->pRecipientPrivateKey
539        = kmem_cache_zalloc(drvRSAPrivateKey_zone, GFP_KERNEL);
540    if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
541        APRINTK("%s():Failed to get memory for MOD EXP CRT"
542            " private key values struct\n", __FUNCTION__);
543        kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
544        krp->krp_status = ENOMEM;
545        return ENOMEM;
546    }
547
548    rsaDecryptOpData->pRecipientPrivateKey->
549        version = CPA_CY_RSA_VERSION_TWO_PRIME;
550    rsaDecryptOpData->pRecipientPrivateKey->
551        privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
552
553    pOutputData = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
554    if (NULL == pOutputData) {
555        APRINTK("%s():Failed to get memory"
556            " for MOD EXP CRT output data\n", __FUNCTION__);
557        kmem_cache_free(drvRSAPrivateKey_zone,
558                rsaDecryptOpData->pRecipientPrivateKey);
559        kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
560        krp->krp_status = ENOMEM;
561        return ENOMEM;
562    }
563
564    rsaDecryptOpData->pRecipientPrivateKey->
565        version = CPA_CY_RSA_VERSION_TWO_PRIME;
566    rsaDecryptOpData->pRecipientPrivateKey->
567        privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
568
569    /* Link parameters */
570    rsaDecryptOpData->inputData.pData =
571        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
572    BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
573              krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
574              crp_nbits);
575
576    icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
577                rsaDecryptOpData->inputData.dataLenInBytes);
578
579    rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
580        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
581    BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
582              prime1P.dataLenInBytes,
583              krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
584              crp_nbits);
585
586    icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
587                privateKeyRep2.prime1P.pData,
588                rsaDecryptOpData->pRecipientPrivateKey->
589                privateKeyRep2.prime1P.dataLenInBytes);
590
591    rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
592        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
593    BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
594              prime2Q.dataLenInBytes,
595              krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
596              crp_nbits);
597
598    icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
599                privateKeyRep2.prime2Q.pData,
600                rsaDecryptOpData->pRecipientPrivateKey->
601                privateKeyRep2.prime2Q.dataLenInBytes);
602
603    rsaDecryptOpData->pRecipientPrivateKey->
604        privateKeyRep2.exponent1Dp.pData =
605        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
606    BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
607              exponent1Dp.dataLenInBytes,
608              krp->
609              krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
610              crp_nbits);
611
612    icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
613                privateKeyRep2.exponent1Dp.pData,
614                rsaDecryptOpData->pRecipientPrivateKey->
615                privateKeyRep2.exponent1Dp.dataLenInBytes);
616
617    rsaDecryptOpData->pRecipientPrivateKey->
618        privateKeyRep2.exponent2Dq.pData =
619        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
620    BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
621              privateKeyRep2.exponent2Dq.dataLenInBytes,
622              krp->
623              krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
624              crp_nbits);
625
626    icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
627                privateKeyRep2.exponent2Dq.pData,
628                rsaDecryptOpData->pRecipientPrivateKey->
629                privateKeyRep2.exponent2Dq.dataLenInBytes);
630
631    rsaDecryptOpData->pRecipientPrivateKey->
632        privateKeyRep2.coefficientQInv.pData =
633        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
634    BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
635              privateKeyRep2.coefficientQInv.dataLenInBytes,
636              krp->
637              krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
638              crp_nbits);
639
640    icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
641                privateKeyRep2.coefficientQInv.pData,
642                rsaDecryptOpData->pRecipientPrivateKey->
643                privateKeyRep2.coefficientQInv.dataLenInBytes);
644
645    /* Output Parameter */
646    pOutputData->pData =
647        krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
648    BITS_TO_BYTES(pOutputData->dataLenInBytes,
649              krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
650              crp_nbits);
651
652    lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
653                    icp_ocfDrvModExpCRTCallBack,
654                    callbackTag, rsaDecryptOpData, pOutputData);
655
656    if (CPA_STATUS_SUCCESS != lacStatus) {
657        EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
658            __FUNCTION__, lacStatus);
659        krp->krp_status = ECANCELED;
660        icp_ocfDrvFreeFlatBuffer(pOutputData);
661        kmem_cache_free(drvRSAPrivateKey_zone,
662                rsaDecryptOpData->pRecipientPrivateKey);
663        kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
664    }
665
666    return lacStatus;
667}
668
669/* Name : icp_ocfDrvCheckALessThanB
670 *
671 * Description : This function will check whether the first argument is less
672 * than the second. It is used to check whether the DSA RS sign Random K
673 * value is less than the Prime Q value (as defined in the specification)
674 *
675 */
676static int
677icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
678{
679
680    uint8_t *MSB_K = pK->pData;
681    uint8_t *MSB_Q = pQ->pData;
682    uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
683
684    if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
685        return FAIL_A_IS_GREATER_THAN_B;
686    }
687
688/*Check MSBs
689if A == B, check next MSB
690if A > B, return A_IS_GREATER_THAN_B
691if A < B, return A_IS_LESS_THAN_B (success)
692*/
693    while (*MSB_K == *MSB_Q) {
694        MSB_K++;
695        MSB_Q++;
696
697        buffer_lengths_in_bytes--;
698        if (0 == buffer_lengths_in_bytes) {
699            DPRINTK("%s() Buffers have equal value!!\n",
700                __FUNCTION__);
701            return FAIL_A_IS_EQUAL_TO_B;
702        }
703
704    }
705
706    if (*MSB_K < *MSB_Q) {
707        return SUCCESS_A_IS_LESS_THAN_B;
708    } else {
709        return FAIL_A_IS_GREATER_THAN_B;
710    }
711
712}
713
714/* Name : icp_ocfDrvDsaSign
715 *
716 * Description : This function will map DSA RS Sign from OCF to the LAC API.
717 *
718 * NOTE: From looking at OCF patch to OpenSSL and even the number of input
719 * parameters, OCF expects us to generate the random seed value. This value
720 * is generated and passed to LAC, however the number is discared in the
721 * callback and not returned to the user.
722 */
723static int icp_ocfDrvDsaSign(struct cryptkop *krp)
724{
725    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
726    CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
727    void *callbackTag = NULL;
728    CpaCyRandGenOpData randGenOpData;
729    int primeQSizeInBytes = 0;
730    int doCheck = 0;
731    CpaFlatBuffer randData;
732    CpaBoolean protocolStatus = CPA_FALSE;
733    CpaFlatBuffer *pR = NULL;
734    CpaFlatBuffer *pS = NULL;
735
736    callbackTag = krp;
737
738    BITS_TO_BYTES(primeQSizeInBytes,
739              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
740              crp_nbits);
741
742    if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
743        APRINTK("%s(): DSA PRIME Q size not equal to the "
744            "FIPS defined 20bytes, = %d\n",
745            __FUNCTION__, primeQSizeInBytes);
746        krp->krp_status = EDOM;
747        return EDOM;
748    }
749
750    dsaRsSignOpData = kmem_cache_zalloc(drvDSARSSign_zone, GFP_KERNEL);
751    if (NULL == dsaRsSignOpData) {
752        APRINTK("%s():Failed to get memory"
753            " for DSA RS Sign Op data struct\n", __FUNCTION__);
754        krp->krp_status = ENOMEM;
755        return ENOMEM;
756    }
757
758    dsaRsSignOpData->K.pData =
759        kmem_cache_alloc(drvDSARSSignKValue_zone, GFP_ATOMIC);
760
761    if (NULL == dsaRsSignOpData->K.pData) {
762        APRINTK("%s():Failed to get memory"
763            " for DSA RS Sign Op Random value\n", __FUNCTION__);
764        kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
765        krp->krp_status = ENOMEM;
766        return ENOMEM;
767    }
768
769    pR = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
770    if (NULL == pR) {
771        APRINTK("%s():Failed to get memory"
772            " for DSA signature R\n", __FUNCTION__);
773        kmem_cache_free(drvDSARSSignKValue_zone,
774                dsaRsSignOpData->K.pData);
775        kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
776        krp->krp_status = ENOMEM;
777        return ENOMEM;
778    }
779
780    pS = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
781    if (NULL == pS) {
782        APRINTK("%s():Failed to get memory"
783            " for DSA signature S\n", __FUNCTION__);
784        icp_ocfDrvFreeFlatBuffer(pR);
785        kmem_cache_free(drvDSARSSignKValue_zone,
786                dsaRsSignOpData->K.pData);
787        kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
788        krp->krp_status = ENOMEM;
789        return ENOMEM;
790    }
791
792    /*link prime number parameter for ease of processing */
793    dsaRsSignOpData->P.pData =
794        krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
795    BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
796              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
797              crp_nbits);
798
799    icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
800                dsaRsSignOpData->P.dataLenInBytes);
801
802    dsaRsSignOpData->Q.pData =
803        krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
804    BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
805              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
806              crp_nbits);
807
808    icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
809                dsaRsSignOpData->Q.dataLenInBytes);
810
811    /*generate random number with equal buffer size to Prime value Q,
812       but value less than Q */
813    dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
814
815    randGenOpData.generateBits = CPA_TRUE;
816    randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
817
818    icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
819                    dsaRsSignOpData->K.dataLenInBytes,
820                    &randData);
821
822    doCheck = 0;
823    while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
824                     &(dsaRsSignOpData->Q), &doCheck)) {
825
826        if (CPA_STATUS_SUCCESS
827            != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
828                    NULL, NULL, &randGenOpData, &randData)) {
829            APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
830                "value\n", __FUNCTION__);
831            icp_ocfDrvFreeFlatBuffer(pS);
832            icp_ocfDrvFreeFlatBuffer(pR);
833            kmem_cache_free(drvDSARSSignKValue_zone,
834                    dsaRsSignOpData->K.pData);
835            kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
836            krp->krp_status = EAGAIN;
837            return EAGAIN;
838        }
839
840        doCheck++;
841        if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
842            APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
843                "value less than Q value\n", __FUNCTION__);
844            icp_ocfDrvFreeFlatBuffer(pS);
845            icp_ocfDrvFreeFlatBuffer(pR);
846            kmem_cache_free(drvDSARSSignKValue_zone,
847                    dsaRsSignOpData->K.pData);
848            kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
849            krp->krp_status = EAGAIN;
850            return EAGAIN;
851        }
852
853    }
854    /*Rand Data - no need to swap bytes for pK */
855
856    /* Link parameters */
857    dsaRsSignOpData->G.pData =
858        krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
859    BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
860              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
861
862    icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
863                dsaRsSignOpData->G.dataLenInBytes);
864
865    dsaRsSignOpData->X.pData =
866        krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
867    BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
868              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
869    icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
870                dsaRsSignOpData->X.dataLenInBytes);
871
872    dsaRsSignOpData->M.pData =
873        krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
874    BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
875              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
876              crp_nbits);
877    icp_ocfDrvSwapBytes(dsaRsSignOpData->M.pData,
878                dsaRsSignOpData->M.dataLenInBytes);
879
880    /* Output Parameters */
881    pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
882    BITS_TO_BYTES(pS->dataLenInBytes,
883              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
884              crp_nbits);
885
886    pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
887    BITS_TO_BYTES(pR->dataLenInBytes,
888              krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
889              crp_nbits);
890
891    lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
892                   icp_ocfDrvDsaRSSignCallBack,
893                   callbackTag, dsaRsSignOpData,
894                   &protocolStatus, pR, pS);
895
896    if (CPA_STATUS_SUCCESS != lacStatus) {
897        EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
898            __FUNCTION__, lacStatus);
899        krp->krp_status = ECANCELED;
900        icp_ocfDrvFreeFlatBuffer(pS);
901        icp_ocfDrvFreeFlatBuffer(pR);
902        kmem_cache_free(drvDSARSSignKValue_zone,
903                dsaRsSignOpData->K.pData);
904        kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
905    }
906
907    return lacStatus;
908}
909
910/* Name : icp_ocfDrvDsaVerify
911 *
912 * Description : This function will map DSA RS Verify from OCF to the LAC API.
913 *
914 */
915static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
916{
917    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
918    CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
919    void *callbackTag = NULL;
920    CpaBoolean verifyStatus = CPA_FALSE;
921
922    callbackTag = krp;
923
924    dsaVerifyOpData = kmem_cache_zalloc(drvDSAVerify_zone, GFP_KERNEL);
925    if (NULL == dsaVerifyOpData) {
926        APRINTK("%s():Failed to get memory"
927            " for DSA Verify Op data struct\n", __FUNCTION__);
928        krp->krp_status = ENOMEM;
929        return ENOMEM;
930    }
931
932    /* Link parameters */
933    dsaVerifyOpData->P.pData =
934        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
935    BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
936              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
937              crp_nbits);
938    icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
939                dsaVerifyOpData->P.dataLenInBytes);
940
941    dsaVerifyOpData->Q.pData =
942        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
943    BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
944              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
945              crp_nbits);
946    icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
947                dsaVerifyOpData->Q.dataLenInBytes);
948
949    dsaVerifyOpData->G.pData =
950        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
951    BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
952              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
953              crp_nbits);
954    icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
955                dsaVerifyOpData->G.dataLenInBytes);
956
957    dsaVerifyOpData->Y.pData =
958        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
959    BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
960              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
961              crp_nbits);
962    icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
963                dsaVerifyOpData->Y.dataLenInBytes);
964
965    dsaVerifyOpData->M.pData =
966        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
967    BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
968              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
969              crp_nbits);
970    icp_ocfDrvSwapBytes(dsaVerifyOpData->M.pData,
971                dsaVerifyOpData->M.dataLenInBytes);
972
973    dsaVerifyOpData->R.pData =
974        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
975    BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
976              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
977              crp_nbits);
978    icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
979                dsaVerifyOpData->R.dataLenInBytes);
980
981    dsaVerifyOpData->S.pData =
982        krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
983    BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
984              krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
985              crp_nbits);
986    icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
987                dsaVerifyOpData->S.dataLenInBytes);
988
989    lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
990                   icp_ocfDrvDsaVerifyCallBack,
991                   callbackTag, dsaVerifyOpData, &verifyStatus);
992
993    if (CPA_STATUS_SUCCESS != lacStatus) {
994        EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
995            __FUNCTION__, lacStatus);
996        kmem_cache_free(drvDSAVerify_zone, dsaVerifyOpData);
997        krp->krp_status = ECANCELED;
998    }
999
1000    return lacStatus;
1001}
1002
1003/* Name : icp_ocfDrvReadRandom
1004 *
1005 * Description : This function will map RNG functionality calls from OCF
1006 * to the LAC API.
1007 */
1008int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords)
1009{
1010    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
1011    CpaCyRandGenOpData randGenOpData;
1012    CpaFlatBuffer randData;
1013
1014    if (NULL == buf) {
1015        APRINTK("%s(): Invalid input parameters\n", __FUNCTION__);
1016        return EINVAL;
1017    }
1018
1019    /* maxwords here is number of integers to generate data for */
1020    randGenOpData.generateBits = CPA_TRUE;
1021
1022    randGenOpData.lenInBytes = maxwords * sizeof(uint32_t);
1023
1024    icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *) buf,
1025                    randGenOpData.lenInBytes, &randData);
1026
1027    lacStatus = cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
1028                 NULL, NULL, &randGenOpData, &randData);
1029    if (CPA_STATUS_SUCCESS != lacStatus) {
1030        EPRINTK("%s(): icp_LacSymRandGen failed (%d). \n",
1031            __FUNCTION__, lacStatus);
1032        return RETURN_RAND_NUM_GEN_FAILED;
1033    }
1034
1035    return randGenOpData.lenInBytes / sizeof(uint32_t);
1036}
1037
1038/* Name : icp_ocfDrvDhP1Callback
1039 *
1040 * Description : When this function returns it signifies that the LAC
1041 * component has completed the DH operation.
1042 */
1043static void
1044icp_ocfDrvDhP1CallBack(void *callbackTag,
1045               CpaStatus status,
1046               void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
1047{
1048    struct cryptkop *krp = NULL;
1049    CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
1050
1051    if (NULL == callbackTag) {
1052        DPRINTK("%s(): Invalid input parameters - "
1053            "callbackTag data is NULL\n", __FUNCTION__);
1054        return;
1055    }
1056    krp = (struct cryptkop *)callbackTag;
1057
1058    if (NULL == pOpData) {
1059        DPRINTK("%s(): Invalid input parameters - "
1060            "Operation Data is NULL\n", __FUNCTION__);
1061        krp->krp_status = ECANCELED;
1062        crypto_kdone(krp);
1063        return;
1064    }
1065    pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
1066
1067    if (NULL == pLocalOctetStringPV) {
1068        DPRINTK("%s(): Invalid input parameters - "
1069            "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
1070        memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
1071        kmem_cache_free(drvDH_zone, pPhase1OpData);
1072        krp->krp_status = ECANCELED;
1073        crypto_kdone(krp);
1074        return;
1075    }
1076
1077    if (CPA_STATUS_SUCCESS == status) {
1078        krp->krp_status = CRYPTO_OP_SUCCESS;
1079    } else {
1080        APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
1081            "Operation Status = %d\n", __FUNCTION__, status);
1082        krp->krp_status = ECANCELED;
1083    }
1084
1085    icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
1086                pLocalOctetStringPV->dataLenInBytes);
1087
1088    icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
1089    memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
1090    kmem_cache_free(drvDH_zone, pPhase1OpData);
1091
1092    crypto_kdone(krp);
1093
1094    return;
1095}
1096
1097/* Name : icp_ocfDrvModExpCallBack
1098 *
1099 * Description : When this function returns it signifies that the LAC
1100 * component has completed the Mod Exp operation.
1101 */
1102static void
1103icp_ocfDrvModExpCallBack(void *callbackTag,
1104             CpaStatus status,
1105             void *pOpdata, CpaFlatBuffer * pResult)
1106{
1107    struct cryptkop *krp = NULL;
1108    CpaCyLnModExpOpData *pLnModExpOpData = NULL;
1109
1110    if (NULL == callbackTag) {
1111        DPRINTK("%s(): Invalid input parameters - "
1112            "callbackTag data is NULL\n", __FUNCTION__);
1113        return;
1114    }
1115    krp = (struct cryptkop *)callbackTag;
1116
1117    if (NULL == pOpdata) {
1118        DPRINTK("%s(): Invalid Mod Exp input parameters - "
1119            "Operation Data is NULL\n", __FUNCTION__);
1120        krp->krp_status = ECANCELED;
1121        crypto_kdone(krp);
1122        return;
1123    }
1124    pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
1125
1126    if (NULL == pResult) {
1127        DPRINTK("%s(): Invalid input parameters - "
1128            "pResult data is NULL\n", __FUNCTION__);
1129        krp->krp_status = ECANCELED;
1130        memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
1131        kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
1132        crypto_kdone(krp);
1133        return;
1134    }
1135
1136    if (CPA_STATUS_SUCCESS == status) {
1137        krp->krp_status = CRYPTO_OP_SUCCESS;
1138    } else {
1139        APRINTK("%s(): LAC Mod Exp Operation failed - "
1140            "Operation Status = %d\n", __FUNCTION__, status);
1141        krp->krp_status = ECANCELED;
1142    }
1143
1144    icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
1145
1146    /*switch base size value back to original */
1147    if (pLnModExpOpData->base.pData ==
1148        (uint8_t *) & (krp->
1149               krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
1150               crp_nbits)) {
1151        *((uint32_t *) pLnModExpOpData->base.pData) =
1152            ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
1153    }
1154    icp_ocfDrvFreeFlatBuffer(pResult);
1155    memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
1156    kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
1157
1158    crypto_kdone(krp);
1159
1160    return;
1161
1162}
1163
1164/* Name : icp_ocfDrvModExpCRTCallBack
1165 *
1166 * Description : When this function returns it signifies that the LAC
1167 * component has completed the Mod Exp CRT operation.
1168 */
1169static void
1170icp_ocfDrvModExpCRTCallBack(void *callbackTag,
1171                CpaStatus status,
1172                void *pOpData, CpaFlatBuffer * pOutputData)
1173{
1174    struct cryptkop *krp = NULL;
1175    CpaCyRsaDecryptOpData *pDecryptData = NULL;
1176
1177    if (NULL == callbackTag) {
1178        DPRINTK("%s(): Invalid input parameters - "
1179            "callbackTag data is NULL\n", __FUNCTION__);
1180        return;
1181    }
1182
1183    krp = (struct cryptkop *)callbackTag;
1184
1185    if (NULL == pOpData) {
1186        DPRINTK("%s(): Invalid input parameters - "
1187            "Operation Data is NULL\n", __FUNCTION__);
1188        krp->krp_status = ECANCELED;
1189        crypto_kdone(krp);
1190        return;
1191    }
1192    pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
1193
1194    if (NULL == pOutputData) {
1195        DPRINTK("%s(): Invalid input parameter - "
1196            "pOutputData is NULL\n", __FUNCTION__);
1197        memset(pDecryptData->pRecipientPrivateKey, 0,
1198               sizeof(CpaCyRsaPrivateKey));
1199        kmem_cache_free(drvRSAPrivateKey_zone,
1200                pDecryptData->pRecipientPrivateKey);
1201        memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
1202        kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
1203        krp->krp_status = ECANCELED;
1204        crypto_kdone(krp);
1205        return;
1206    }
1207
1208    if (CPA_STATUS_SUCCESS == status) {
1209        krp->krp_status = CRYPTO_OP_SUCCESS;
1210    } else {
1211        APRINTK("%s(): LAC Mod Exp CRT operation failed - "
1212            "Operation Status = %d\n", __FUNCTION__, status);
1213        krp->krp_status = ECANCELED;
1214    }
1215
1216    icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
1217
1218    icp_ocfDrvFreeFlatBuffer(pOutputData);
1219    memset(pDecryptData->pRecipientPrivateKey, 0,
1220           sizeof(CpaCyRsaPrivateKey));
1221    kmem_cache_free(drvRSAPrivateKey_zone,
1222            pDecryptData->pRecipientPrivateKey);
1223    memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
1224    kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
1225
1226    crypto_kdone(krp);
1227
1228    return;
1229}
1230
1231/* Name : icp_ocfDrvDsaRSSignCallBack
1232 *
1233 * Description : When this function returns it signifies that the LAC
1234 * component has completed the DSA RS sign operation.
1235 */
1236static void
1237icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
1238                CpaStatus status,
1239                void *pOpData,
1240                CpaBoolean protocolStatus,
1241                CpaFlatBuffer * pR, CpaFlatBuffer * pS)
1242{
1243    struct cryptkop *krp = NULL;
1244    CpaCyDsaRSSignOpData *pSignData = NULL;
1245
1246    if (NULL == callbackTag) {
1247        DPRINTK("%s(): Invalid input parameters - "
1248            "callbackTag data is NULL\n", __FUNCTION__);
1249        return;
1250    }
1251
1252    krp = (struct cryptkop *)callbackTag;
1253
1254    if (NULL == pOpData) {
1255        DPRINTK("%s(): Invalid input parameters - "
1256            "Operation Data is NULL\n", __FUNCTION__);
1257        krp->krp_status = ECANCELED;
1258        crypto_kdone(krp);
1259        return;
1260    }
1261    pSignData = (CpaCyDsaRSSignOpData *) pOpData;
1262
1263    if (NULL == pR) {
1264        DPRINTK("%s(): Invalid input parameter - "
1265            "pR sign is NULL\n", __FUNCTION__);
1266        icp_ocfDrvFreeFlatBuffer(pS);
1267        kmem_cache_free(drvDSARSSign_zone, pSignData);
1268        krp->krp_status = ECANCELED;
1269        crypto_kdone(krp);
1270        return;
1271    }
1272
1273    if (NULL == pS) {
1274        DPRINTK("%s(): Invalid input parameter - "
1275            "pS sign is NULL\n", __FUNCTION__);
1276        icp_ocfDrvFreeFlatBuffer(pR);
1277        kmem_cache_free(drvDSARSSign_zone, pSignData);
1278        krp->krp_status = ECANCELED;
1279        crypto_kdone(krp);
1280        return;
1281    }
1282
1283    if (CPA_STATUS_SUCCESS != status) {
1284        APRINTK("%s(): LAC DSA RS Sign operation failed - "
1285            "Operation Status = %d\n", __FUNCTION__, status);
1286        krp->krp_status = ECANCELED;
1287    } else {
1288        krp->krp_status = CRYPTO_OP_SUCCESS;
1289
1290        if (CPA_TRUE != protocolStatus) {
1291            DPRINTK("%s(): LAC DSA RS Sign operation failed due "
1292                "to protocol error\n", __FUNCTION__);
1293            krp->krp_status = EIO;
1294        }
1295    }
1296
1297    /* Swap bytes only when the callback status is successful and
1298       protocolStatus is set to true */
1299    if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
1300        icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
1301        icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
1302    }
1303
1304    icp_ocfDrvFreeFlatBuffer(pR);
1305    icp_ocfDrvFreeFlatBuffer(pS);
1306    memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
1307    kmem_cache_free(drvDSARSSignKValue_zone, pSignData->K.pData);
1308    memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
1309    kmem_cache_free(drvDSARSSign_zone, pSignData);
1310    crypto_kdone(krp);
1311
1312    return;
1313}
1314
1315/* Name : icp_ocfDrvDsaVerifyCallback
1316 *
1317 * Description : When this function returns it signifies that the LAC
1318 * component has completed the DSA Verify operation.
1319 */
1320static void
1321icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
1322                CpaStatus status,
1323                void *pOpData, CpaBoolean verifyStatus)
1324{
1325
1326    struct cryptkop *krp = NULL;
1327    CpaCyDsaVerifyOpData *pVerData = NULL;
1328
1329    if (NULL == callbackTag) {
1330        DPRINTK("%s(): Invalid input parameters - "
1331            "callbackTag data is NULL\n", __FUNCTION__);
1332        return;
1333    }
1334
1335    krp = (struct cryptkop *)callbackTag;
1336
1337    if (NULL == pOpData) {
1338        DPRINTK("%s(): Invalid input parameters - "
1339            "Operation Data is NULL\n", __FUNCTION__);
1340        krp->krp_status = ECANCELED;
1341        crypto_kdone(krp);
1342        return;
1343    }
1344    pVerData = (CpaCyDsaVerifyOpData *) pOpData;
1345
1346    if (CPA_STATUS_SUCCESS != status) {
1347        APRINTK("%s(): LAC DSA Verify operation failed - "
1348            "Operation Status = %d\n", __FUNCTION__, status);
1349        krp->krp_status = ECANCELED;
1350    } else {
1351        krp->krp_status = CRYPTO_OP_SUCCESS;
1352
1353        if (CPA_TRUE != verifyStatus) {
1354            DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
1355            krp->krp_status = EIO;
1356        }
1357    }
1358
1359    /* Swap bytes only when the callback status is successful and
1360       verifyStatus is set to true */
1361    /*Just swapping back the key values for now. Possibly all
1362       swapped buffers need to be reverted */
1363    if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
1364        icp_ocfDrvSwapBytes(pVerData->R.pData,
1365                    pVerData->R.dataLenInBytes);
1366        icp_ocfDrvSwapBytes(pVerData->S.pData,
1367                    pVerData->S.dataLenInBytes);
1368    }
1369
1370    memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
1371    kmem_cache_free(drvDSAVerify_zone, pVerData);
1372    crypto_kdone(krp);
1373
1374    return;
1375}
1376

Archive Download this file



interactive