2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
5 * NBMK Encryption Technologies provides no support of any kind for
6 * this software. Questions or concerns about it may be addressed to
7 * the members of the relevant open-source community at
8 * <tech-crypto@netbsd.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 static char const n8_id
[] = "$Id: n8_cb_dsa.c,v 1.1 2008/10/30 12:02:15 darran Exp $";
36 /*****************************************************************************/
38 * @brief DSA Command Block Generator
40 * Generates all command blocks for DSA-related functions.
42 *****************************************************************************/
44 /*****************************************************************************
46 * 09/10/02 brr Set command complete bit on last command block.
47 * 02/20/02 brr Removed references to the queue structure.
48 * 11/12/01 hml Fixed some debugging code.
49 * 10/31/01 bac Added support for SKS.
50 * 09/14/01 bac Use new DBG_PRINT_PK_CMD_BLOCKS macros.
51 * 08/24/01 bac Changed all methods to accept the pre-allocated command
53 * 07/30/01 bac Pass queue pointer to all length calculation macros.
54 * 07/12/01 bac Removed unused variables.
55 * 07/13/01 mel Fixed bug in cb_dsaVerify:
56 * command loaded wrong number of gR_mod_p bytes.
57 * 06/28/01 mel Fixed bug (kernel memory usage).
59 * 06/28/01 bac Minor typo corrections.
60 * 06/26/01 bac Even more on conversion to use physical memory.
61 * 06/25/01 bac More on conversion to use physical memory.
62 * 06/20/01 mel Corrected use of kernel memory.
63 * 05/22/01 mel Original version.
64 ****************************************************************************/
65 /** @defgroup cb_dsa DSA Command Block Generator
68 #include "n8_common.h"
69 #include "n8_pk_common.h"
70 #include "n8_pub_errors.h"
71 #include "n8_cb_dsa.h"
74 /* #define ZERO_CMD_BLOCK(X) memset((X), 0, sizeof(PK_CMD_BLOCK_t)) */
75 #define ZERO_CMD_BLOCK(X)
77 /*****************************************************************************
79 *****************************************************************************/
81 * @brief Creates the command blocks to compute the value for gR mod X
84 * @param req_p RW: Pointer to command
86 * @param key RO: pointer to phisical addresses of DSAObject.
87 * @param modulusDigits RO: number of digits in modulus p.
90 * ret - returns N8_STATUS_OK if successful or Error value.
93 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
94 * N8_MALLOC_FAILED - memory allocation failed<BR>
98 *****************************************************************************/
100 N8_Status_t
cb_computeGRmodX(API_Request_t
*req_p
,
101 const int modulusDigits
,
105 PK_CMD_BLOCK_t
*cmdBuf_p
,
106 PK_CMD_BLOCK_t
**next_cmdBuf_p
)
108 PK_CMD_BLOCK_t
*math_wr_ptr
= NULL
;
109 PK_LDST_CMD_BLOCK_t
*ldst_wr_ptr
= NULL
;
111 uint32_t slot0
, slot1
, slot2
, slot3
;
113 N8_Status_t ret
= N8_STATUS_OK
;
117 CHECK_OBJECT(req_p
, ret
);
119 /* Initialize the slot values. These are to address temporary
120 storage in the BNC. The slots accomodate operand sizes up to
123 slot1
= modulusDigits
;
124 slot2
= modulusDigits
* 2;
125 slot3
= modulusDigits
* 3;
127 /* Compute gR mod p */
128 /* 1) Construct a command to load p */
130 * slot0 slot1 slot2 slot3
133 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) cmdBuf_p
;
134 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
135 ldst_wr_ptr
->r_offset
= slot1
;
136 ldst_wr_ptr
->data_addr_ls
= X_a
;
137 ldst_wr_ptr
->data_length
= PK_DSA_P_Byte_Length(modulusDigits
);
139 /* 2) Construct a command to load g */
141 * slot0 slot1 slot2 slot3
144 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
145 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
146 ldst_wr_ptr
->r_offset
= slot2
;
147 ldst_wr_ptr
->data_addr_ls
= g_a
;
148 ldst_wr_ptr
->data_length
= PK_DSA_G_Byte_Length(modulusDigits
);
150 /* 3) Construct a command for the operation R mod p */
152 * slot0 slot1 slot2 slot3
155 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
156 math_wr_ptr
->opcode_si
= PK_Cmd_R_Mod_M
;
157 math_wr_ptr
->r_offset
= slot3
;
158 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
159 PK_Cmd_Length_Shift
) | slot1
;
161 /* 4) Construct a command for the operation g * Rmodp mod p */
163 * slot0 slot1 slot2 slot3
166 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
167 math_wr_ptr
->opcode_si
= PK_Cmd_AB_Mod_M
;
168 math_wr_ptr
->r_offset
= slot0
;
169 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
170 PK_Cmd_Length_Shift
) | slot1
;
171 math_wr_ptr
->a_length_offset
= (PK_DSA_G_BNC_Length(modulusDigits
) <<
172 PK_Cmd_Length_Shift
) | slot2
;
173 math_wr_ptr
->b_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
174 PK_Cmd_Length_Shift
) | slot3
;
176 /* 5) Construct a command to store gR mod p */
177 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
178 ldst_wr_ptr
->opcode_si
= PK_Cmd_Store_R
;
179 ldst_wr_ptr
->r_offset
= slot0
;
180 ldst_wr_ptr
->data_addr_ls
= res_a
;
181 ldst_wr_ptr
->data_length
= PK_DSA_GR_MOD_P_Byte_Length(modulusDigits
);
183 /* save next address for future use */
184 *next_cmdBuf_p
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
186 DBG(("Compute gR mod X\n"));
187 /* DBG_PRINT_CMD_BLOCKS("Compute gR mod X",
188 (PK_CMD_BLOCK_t *) req_p->PK_CommandBlock_ptr,
189 N8_CB_COMPUTE_GRMODX_NUMCMDS); */
193 } /* computeGRmodX */
195 /*****************************************************************************
197 *****************************************************************************/
199 * @brief Creates the command blocks to compute DSA signature
202 * @param req_p RW: Pointer to command
204 * @param key RO: The previously initialized DSAKeyObject
205 * containing the DSA key
206 * materials to be used.
207 * @param n_a RO: Physical address of random number n.
208 * @param paramBlock_a RO: Physical address of parameters block.
209 * @param msgHash_a RO: Physical address of hash.
210 * @param rValue_a RO: Physical address of r value.
211 * @param sValue_a RO: Physical address of s value.
214 * ret - returns N8_STATUS_OK if successful or Error value.
217 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
218 * N8_MALLOC_FAILED - memory allocation failed<BR>
222 *****************************************************************************/
223 N8_Status_t
cb_dsaSign(API_Request_t
*req_p
,
224 const N8_DSAKeyObject_t
*key_p
,
226 uint32_t paramBlock_a
,
230 PK_CMD_BLOCK_t
*cmdBuf_p
)
232 PK_RSA_CMD_BLOCK_t
*math_wr_ptr
= NULL
;
233 PK_LDST_CMD_BLOCK_t
*ldst_wr_ptr
= NULL
;
234 uint32_t modulusDigits
;
236 N8_Status_t ret
= N8_STATUS_OK
;
240 CHECK_OBJECT(req_p
, ret
);
241 CHECK_OBJECT(key_p
, ret
);
243 modulusDigits
= BYTES_TO_PKDIGITS(key_p
->modulusLength
);
245 DBG(("constructing sign command blocks\n"));
247 /* 1) Construct a command to load random number n */
248 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) cmdBuf_p
;
249 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
250 ldst_wr_ptr
->r_offset
= PK_DSA_N_BNC_Offset
;
251 ldst_wr_ptr
->data_addr_ls
= n_a
;
252 ldst_wr_ptr
->data_length
= PK_DSA_N_Byte_Length
;
254 /* 2) Construct a command to load hash e1 */
255 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
256 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
257 ldst_wr_ptr
->r_offset
= PK_DSA_E1_BNC_Offset
;
258 ldst_wr_ptr
->data_addr_ls
= msgHash_a
;
259 ldst_wr_ptr
->data_length
= PK_DSA_E1_Byte_Length
;
261 if (key_p
->keyType
== N8_PRIVATE_SKS
)
263 /* we are using the sks. set the sks_word variable to the correct
264 * offset. We do not need to load the DSA parameter block as it is
265 * already in the SKS. */
266 sks_word
= key_p
->SKSKeyHandle
.sks_offset
;
270 /* 3) Construct a command to load the DSA parameter block */
271 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
272 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
273 ldst_wr_ptr
->r_offset
= PK_DSA_P_BNC_Offset
;
274 ldst_wr_ptr
->data_addr_ls
= paramBlock_a
;
275 ldst_wr_ptr
->data_length
= PK_DSA_Param_Byte_Length(modulusDigits
);
277 sks_word
= PK_Cmd_N_Mask
;
280 /* 4) Construct a command for the DSA operation */
281 math_wr_ptr
= (PK_RSA_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
282 math_wr_ptr
->opcode_si
= PK_Cmd_DSA_Sign_Op
;
283 math_wr_ptr
->sks
= sks_word
| (modulusDigits
<< PK_Cmd_Key_Length_Shift
);
285 /* 5) Construct a command to store r */
286 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
287 ldst_wr_ptr
->opcode_si
= PK_Cmd_Store_R
;
288 ldst_wr_ptr
->r_offset
= PK_DSA_R_BNC_Offset
;
289 ldst_wr_ptr
->data_addr_ls
= rValue_a
;
290 ldst_wr_ptr
->data_length
= PK_DSA_R_Byte_Length
;
292 /* 6) Construct a command to store s */
293 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
294 ldst_wr_ptr
->opcode_si
= PK_Cmd_Store_R
| PK_Cmd_SI_Mask
;
295 ldst_wr_ptr
->r_offset
= PK_DSA_S_BNC_Offset
;
296 ldst_wr_ptr
->data_addr_ls
= sValue_a
;
297 ldst_wr_ptr
->data_length
= PK_DSA_S_Byte_Length
;
300 DBG_PRINT_PK_CMD_BLOCKS("DSA sign",
301 req_p
->PK_CommandBlock_ptr
,
302 N8_CB_DSA_SIGN_NUMCMDS(key_p
));
307 /*****************************************************************************
309 *****************************************************************************/
311 * @brief Creates the command blocks to perform DSA verify operation
313 * 1) Compute e = e1 mod q
314 * 2) Compute invs = s^1 mod q
315 * 3) Compute u1 = invs * e mod q
316 * 4) Compute u2 = invs * r mod q
317 * 5) Compute v1 = g^u1 mod p
318 * 6) Compute w = y^u2 mod p
319 * 7) Compute v3 = v1 * w mod p
320 * 8) Compute v = v3 mod q
323 * Big Number Cache slot allocation
326 * -------------------------------------------------------------------------
334 * step 5) . p[0] . . 2^128
341 * step 6) . . . . Rmodp . y
349 * @param req_p RW: Pointer to command
351 * @param key RO: The previously initialized DSAKeyObject
352 * containing the DSA key
353 * materials to be used.
354 * @param q_a RO: Physical address of q value.
355 * @param cp_a RO: Physical address of computed cp.
356 * @param gR_mod_p_a RO: Physical address of computed gRmodp.
357 * @param p_a RO: Physical address of p value.
358 * @param publicKey_a RO: Physical address of public key.
359 * @param mh_a RO: Physical address of hash.
360 * @param r_a RO: Physical address of r value.
361 * @param s_a RO: Physical address of s value.
362 * @param res_a WO: Physical address of result.
365 * ret - returns N8_STATUS_OK if successful or Error value.
368 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
369 * N8_MALLOC_FAILED - memory allocation failed<BR>
373 *****************************************************************************/
374 N8_Status_t
cb_dsaVerify(API_Request_t
*req_p
,
375 const N8_DSAKeyObject_t
*key_p
,
380 uint32_t publicKey_a
,
385 PK_CMD_BLOCK_t
*cmdBuf_p
)
387 PK_CMD_BLOCK_t
*math_wr_ptr
= NULL
;
388 PK_LDST_CMD_BLOCK_t
*ldst_wr_ptr
= NULL
;
390 uint32_t modulusDigits
;
391 uint32_t slot1
, slot2
, slot3
, slot4
;
392 uint32_t slot5
, slot6
, slot7
, slot8
;
394 N8_Status_t ret
= N8_STATUS_OK
;
398 CHECK_OBJECT(req_p
, ret
);
400 modulusDigits
= BYTES_TO_PKDIGITS(key_p
->modulusLength
);
402 /* Initialize the slot values. These are to address temporary
403 storage in the BNC. Slots 1-4 hold 2-digit operands.
404 Slots 5-8 hold operands up to the key size in length. */
406 slot2
= slot1
+ PK_DSA_N_BNC_Length
; /* invs */
407 slot3
= slot2
+ PK_DSA_N_BNC_Length
; /* e1 */
408 slot4
= slot3
+ PK_DSA_N_BNC_Length
; /* */
409 slot5
= slot4
+ modulusDigits
;
410 slot6
= slot5
+ modulusDigits
;
411 slot7
= slot6
+ modulusDigits
;
412 slot8
= slot7
+ modulusDigits
;
417 /* 1) Construct a command to load q */
421 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) cmdBuf_p
;
422 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
423 ldst_wr_ptr
->r_offset
= slot1
;
424 ldst_wr_ptr
->data_addr_ls
= (unsigned int) q_a
;
425 ldst_wr_ptr
->data_length
= PK_DSA_Q_Byte_Length
;
428 /* 2)Construct a command to load e1 */
432 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
433 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
434 ldst_wr_ptr
->r_offset
= slot3
;
435 ldst_wr_ptr
->data_addr_ls
= mh_a
;
436 ldst_wr_ptr
->data_length
= PK_DSA_E1_Byte_Length
;
438 /* 3) Construct a command for the operation e1 mod q */
442 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
443 math_wr_ptr
->opcode_si
= PK_Cmd_A_Mod_M
;
444 math_wr_ptr
->r_offset
= slot4
;
445 math_wr_ptr
->m_length_offset
= (PK_DSA_Q_BNC_Length
<<
446 PK_Cmd_Length_Shift
) | slot1
;
447 math_wr_ptr
->a_length_offset
= (PK_DSA_E1_BNC_Length
<<
448 PK_Cmd_Length_Shift
) | slot3
;
450 /* Compute invs = s^-1 mod q */
451 /* 4) Construct a command to load s */
455 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) math_wr_ptr
+ 1;
456 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
457 ldst_wr_ptr
->r_offset
= slot3
;
458 ldst_wr_ptr
->data_addr_ls
= s_a
;
459 ldst_wr_ptr
->data_length
= PK_DSA_S_Byte_Length
;
461 /* 5) Construct a command for the operation invs = s^-1 mod q */
465 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
466 math_wr_ptr
->opcode_si
= PK_Cmd_Inverse_A_Mod_M
;
467 math_wr_ptr
->r_offset
= slot2
;
468 math_wr_ptr
->m_length_offset
= (PK_DSA_Q_BNC_Length
<<
469 PK_Cmd_Length_Shift
) | slot1
;
470 math_wr_ptr
->a_length_offset
= (PK_DSA_S_BNC_Length
<<
471 PK_Cmd_Length_Shift
) | slot3
;
473 /* Compute u1 = invs * e mod q */
474 /* 6) Construct a command for the operation u1 = invs * e mod q */
478 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
479 math_wr_ptr
->opcode_si
= PK_Cmd_AB_Mod_M
;
480 math_wr_ptr
->r_offset
= slot4
;
481 math_wr_ptr
->m_length_offset
= (PK_DSA_Q_BNC_Length
<<
482 PK_Cmd_Length_Shift
) | slot1
;
483 math_wr_ptr
->a_length_offset
= (PK_DSA_Q_BNC_Length
<<
484 PK_Cmd_Length_Shift
) | slot2
;
485 math_wr_ptr
->b_length_offset
= (PK_DSA_Q_BNC_Length
<<
486 PK_Cmd_Length_Shift
) | slot4
;
488 /* Compute u2 = invs * r mod q */
489 /* 7) Construct a command to load r */
493 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
494 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
495 ldst_wr_ptr
->r_offset
= slot3
;
496 ldst_wr_ptr
->data_addr_ls
= r_a
;
497 ldst_wr_ptr
->data_length
= PK_DSA_R_Byte_Length
;
499 /* 8) Construct a command for the operation u2 = invs * r mod q */
503 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
504 math_wr_ptr
->opcode_si
= PK_Cmd_AB_Mod_M
;
505 math_wr_ptr
->r_offset
= slot3
;
506 math_wr_ptr
->m_length_offset
= (PK_DSA_Q_BNC_Length
<<
507 PK_Cmd_Length_Shift
) | slot1
;
508 math_wr_ptr
->a_length_offset
= (PK_DSA_Q_BNC_Length
<<
509 PK_Cmd_Length_Shift
) | slot2
;
510 math_wr_ptr
->b_length_offset
= (PK_DSA_R_BNC_Length
<<
511 PK_Cmd_Length_Shift
) | slot3
;
513 /* Compute v1 = g^u1 mod p */
515 /* 9) Construct a command to load cp = -t mod 2^128 */
519 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
520 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
521 ldst_wr_ptr
->r_offset
= slot2
;
522 ldst_wr_ptr
->data_addr_ls
= (unsigned int) cp_a
;
523 ldst_wr_ptr
->data_length
= PK_DSA_CP_Byte_Length
;
525 /* 10) Construct a command to load g * R mod p */
529 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
530 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
531 ldst_wr_ptr
->r_offset
= slot6
;
532 ldst_wr_ptr
->data_addr_ls
= gR_mod_p_a
;
533 ldst_wr_ptr
->data_length
= PK_DSA_GR_MOD_P_Byte_Length(modulusDigits
);
535 /* 11) Construct a command to load p */
539 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
540 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
541 ldst_wr_ptr
->r_offset
= slot5
;
542 ldst_wr_ptr
->data_addr_ls
= (unsigned int) p_a
;
543 ldst_wr_ptr
->data_length
= PK_DSA_P_Byte_Length(modulusDigits
);
545 /* 12) Construct a command for the operation v1 = g^u1 mod p */
547 q cp u2 u1 p gR_mod_p
549 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
550 math_wr_ptr
->opcode_si
= PK_Cmd_Exp_G_Mod_M
;
551 math_wr_ptr
->r_offset
= slot7
;
552 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
553 PK_Cmd_Length_Shift
) | slot5
;
554 math_wr_ptr
->a_length_offset
= (PK_DSA_GR_MOD_P_BNC_Length(modulusDigits
) <<
555 PK_Cmd_Length_Shift
) | slot6
;
556 math_wr_ptr
->b_length_offset
= (PK_DSA_Q_BNC_Length
<<
557 PK_Cmd_Length_Shift
) | slot4
;
558 math_wr_ptr
->c_offset
= slot2
;
561 /* Compute w = y^u2 mod p */
562 /* 13) Construct a command to load y */
564 q cp u2 u1 p gR_mod_p v1
566 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
567 ldst_wr_ptr
->opcode_si
= PK_Cmd_Load_R
;
568 ldst_wr_ptr
->r_offset
= slot8
;
569 ldst_wr_ptr
->data_addr_ls
= (unsigned int) publicKey_a
;
570 ldst_wr_ptr
->data_length
= PK_DSA_Y_Byte_Length(modulusDigits
);
572 /* 14) Construct a command for the operation R mod p */
574 q cp u2 u1 p gR_mod_p v1 publicKey
576 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (ldst_wr_ptr
+ 1);
577 math_wr_ptr
->opcode_si
= PK_Cmd_R_Mod_M
;
578 math_wr_ptr
->r_offset
= slot6
;
579 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
580 PK_Cmd_Length_Shift
) | slot5
;
582 /* 15) Construct a command for the operation yR mod p */
584 q cp u2 u1 p R_mod_p v1 publicKey(y)
586 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
587 math_wr_ptr
->opcode_si
= PK_Cmd_AB_Mod_M
;
588 math_wr_ptr
->r_offset
= slot6
;
589 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
590 PK_Cmd_Length_Shift
) | slot5
;
591 math_wr_ptr
->a_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
592 PK_Cmd_Length_Shift
) | slot8
;
593 math_wr_ptr
->b_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
594 PK_Cmd_Length_Shift
) | slot6
;
596 /* 16) Construct a command for the operation w = y^u2 mod p */
598 q cp u2 u1 p yR_mod_p v1 publicKey(y)
600 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
601 math_wr_ptr
->opcode_si
= PK_Cmd_Exp_G_Mod_M
;
602 math_wr_ptr
->r_offset
= slot8
;
603 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
604 PK_Cmd_Length_Shift
) | slot5
;
605 math_wr_ptr
->a_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
606 PK_Cmd_Length_Shift
) | slot6
;
607 math_wr_ptr
->b_length_offset
= (PK_DSA_Q_BNC_Length
<<
608 PK_Cmd_Length_Shift
) | slot3
;
609 math_wr_ptr
->c_offset
= slot2
;
611 /* Compute v3 = v1 * w mod p */
612 /* 17) Construct a command for the operation v3 = v1 * w mod p */
614 q cp u2 u1 p yR_mod_p v1 w
616 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
617 math_wr_ptr
->opcode_si
= PK_Cmd_AB_Mod_M
;
618 math_wr_ptr
->r_offset
= slot7
;
619 math_wr_ptr
->m_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
620 PK_Cmd_Length_Shift
) | slot5
;
621 math_wr_ptr
->a_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
622 PK_Cmd_Length_Shift
) | slot7
;
623 math_wr_ptr
->b_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
624 PK_Cmd_Length_Shift
) | slot8
;
626 /* Compute v = v3 mod q */
627 /* 18) Construct a command for the operation v = v3 mod q */
629 q cp u2 u1 p yR_mod_p v3 w
631 math_wr_ptr
= (PK_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
632 math_wr_ptr
->opcode_si
= PK_Cmd_A_Mod_M
;
633 math_wr_ptr
->r_offset
= slot1
;
634 math_wr_ptr
->m_length_offset
= (PK_DSA_Q_BNC_Length
<<
635 PK_Cmd_Length_Shift
) | slot1
;
636 math_wr_ptr
->a_length_offset
= (PK_DSA_P_BNC_Length(modulusDigits
) <<
637 PK_Cmd_Length_Shift
) | slot7
;
639 /* 19) Construct a command to store v */
641 v cp u2 u1 p yR_mod_p v3 w
643 ldst_wr_ptr
= (PK_LDST_CMD_BLOCK_t
*) (math_wr_ptr
+ 1);
644 ldst_wr_ptr
->opcode_si
= PK_Cmd_Store_R
| PK_Cmd_SI_Mask
;
645 ldst_wr_ptr
->r_offset
= slot1
;
646 ldst_wr_ptr
->data_addr_ls
= res_a
;
647 ldst_wr_ptr
->data_length
= PK_DSA_Q_Byte_Length
;
650 DBG_PRINT_PK_CMD_BLOCKS("DSA verify",
651 (PK_CMD_BLOCK_t
*) req_p
->PK_CommandBlock_ptr
,
652 N8_CB_DSA_VERIFY_NUMCMDS
);
659 /*****************************************************************************
660 * cb_DSASignOperations
661 *****************************************************************************/
663 * @brief Calculate the number of operations required for an DSA Sign.
665 * The operations used to perform an DSA Sign depend upon the key type. If the
666 * type is N8_PRIVATE_SKS, then the DSA Sign Operation will use the parameter
667 * block taken from the SKS, saving a load. If it is not SKS then the parameter
668 * block must be manually loaded and used.
670 * @param key_p RO: Pointer to the key object.
676 * number of commands necessary
682 * The key pointer is valid. We assume this has been checked by the API.
683 *****************************************************************************/
684 unsigned int cb_DSASignOperations(const N8_DSAKeyObject_t
*key_p
)
686 unsigned int ret
= 0;
687 const int NOT_USING_SKS_NUM_COMMANDS
= 6;
689 if (key_p
->keyType
== N8_PRIVATE_SKS
)
691 ret
= NOT_USING_SKS_NUM_COMMANDS
- 1;
695 ret
= NOT_USING_SKS_NUM_COMMANDS
;
698 } /* cb_RSADecryptOperations */