No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / pci / n8 / common / api / commands / n8_cb_dsa.c
blobf0b3033ad0a5c9916ec727db5f70aa292678baf0
1 /*-
2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
3 * All rights reserved.
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>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
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 /*****************************************************************************/
37 /** @file n8_cb_dsa.c
38 * @brief DSA Command Block Generator
40 * Generates all command blocks for DSA-related functions.
42 *****************************************************************************/
44 /*****************************************************************************
45 * Revision history:
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
52 * buffer.
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).
58 * Added comments.
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"
72 #include "n8_util.h"
74 /* #define ZERO_CMD_BLOCK(X) memset((X), 0, sizeof(PK_CMD_BLOCK_t)) */
75 #define ZERO_CMD_BLOCK(X)
77 /*****************************************************************************
78 * cb_computeGRmodX
79 *****************************************************************************/
80 /** @ingroup cb_dsa
81 * @brief Creates the command blocks to compute the value for gR mod X
84 * @param req_p RW: Pointer to command
85 * blocks.
86 * @param key RO: pointer to phisical addresses of DSAObject.
87 * @param modulusDigits RO: number of digits in modulus p.
89 * @return
90 * ret - returns N8_STATUS_OK if successful or Error value.
92 * @par Errors
93 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
94 * N8_MALLOC_FAILED - memory allocation failed<BR>
96 * @par Assumptions
97 * None.<br>
98 *****************************************************************************/
100 N8_Status_t cb_computeGRmodX(API_Request_t *req_p,
101 const int modulusDigits,
102 uint32_t g_a,
103 uint32_t X_a,
104 uint32_t res_a,
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
121 the key length */
122 slot0 = 0;
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
142 * p g
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
153 * p g R mod p
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
164 * gRmodp p g R mod p
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); */
190 } while (FALSE);
192 return ret;
193 } /* computeGRmodX */
195 /*****************************************************************************
196 * cb_dsaSign
197 *****************************************************************************/
198 /** @ingroup cb_dsa
199 * @brief Creates the command blocks to compute DSA signature
202 * @param req_p RW: Pointer to command
203 * blocks.
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.
213 * @return
214 * ret - returns N8_STATUS_OK if successful or Error value.
216 * @par Errors
217 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
218 * N8_MALLOC_FAILED - memory allocation failed<BR>
220 * @par Assumptions
221 * None.<br>
222 *****************************************************************************/
223 N8_Status_t cb_dsaSign(API_Request_t *req_p,
224 const N8_DSAKeyObject_t *key_p,
225 uint32_t n_a,
226 uint32_t paramBlock_a,
227 uint32_t msgHash_a,
228 uint32_t rValue_a,
229 uint32_t sValue_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;
235 uint32_t sks_word;
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;
268 else
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));
303 } while (FALSE);
304 return ret;
307 /*****************************************************************************
308 * cb_dsaVerify
309 *****************************************************************************/
310 /** @ingroup cb_dsa
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
325 * 1 2 3 4 5 6 7 8
326 * -------------------------------------------------------------------------
327 * step 1) q e1
328 * . e
329 * step 2) . s
330 * . invs
331 * step 3) . . u1
332 * step 4) . . r .
333 * . . u2 .
334 * step 5) . p[0] . . 2^128
335 * . p[0]^-1 . . .
336 * . -p[0]^-1 . . .
337 * . . . . p g
338 * . . . . . Rmodp .
339 * . . . . . gRmodp .
340 * . . . . . v1
341 * step 6) . . . . Rmodp . y
342 * . . . . yRmodp .
343 * . . . . . w
344 * step 7) . . v3
345 * step 8) v
349 * @param req_p RW: Pointer to command
350 * blocks.
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.
364 * @return
365 * ret - returns N8_STATUS_OK if successful or Error value.
367 * @par Errors
368 * N8_INVALID_OBJECT - command block pointer is NULL<BR>
369 * N8_MALLOC_FAILED - memory allocation failed<BR>
371 * @par Assumptions
372 * None.<br>
373 *****************************************************************************/
374 N8_Status_t cb_dsaVerify(API_Request_t *req_p,
375 const N8_DSAKeyObject_t *key_p,
376 uint32_t q_a,
377 uint32_t cp_a,
378 uint32_t gR_mod_p_a,
379 uint32_t p_a,
380 uint32_t publicKey_a,
381 uint32_t mh_a,
382 uint32_t r_a,
383 uint32_t s_a,
384 uint32_t res_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. */
405 slot1 = 0; /* q */
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;
415 Compute e = e1 mod q
417 /* 1) Construct a command to load q */
418 /* 1 2 3 4 5 6 7 8
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 */
429 /* 1 2 3 4 5 6 7 8
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 */
439 /* 1 2 3 4 5 6 7 8
440 q e1
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 */
452 /* 1 2 3 4 5 6 7 8
453 q e1 e1 mod q
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 */
462 /* 1 2 3 4 5 6 7 8
463 q s e1 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 */
475 /* 1 2 3 4 5 6 7 8
476 q invs s e1 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 */
490 /* 1 2 3 4 5 6 7 8
491 q invs s u1
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 */
500 /* 1 2 3 4 5 6 7 8
501 q invs r u1
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 */
516 /* 1 2 3 4 5 6 7 8
517 q invs u2 u1
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 */
526 /* 1 2 3 4 5 6 7 8
527 q cp u2 u1
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 */
536 /* 1 2 3 4 5 6 7 8
537 q cp u2 u1 gR_mod_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 */
546 /* 1 2 3 4 5 6 7 8
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 */
563 /* 1 2 3 4 5 6 7 8
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 */
573 /* 1 2 3 4 5 6 7 8
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 */
583 /* 1 2 3 4 5 6 7 8
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 */
597 /* 1 2 3 4 5 6 7 8
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 */
613 /* 1 2 3 4 5 6 7 8
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 */
628 /* 1 2 3 4 5 6 7 8
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 */
640 /* 1 2 3 4 5 6 7 8
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);
653 } while (FALSE);
655 return ret;
657 } /* cb_dsaVerify */
659 /*****************************************************************************
660 * cb_DSASignOperations
661 *****************************************************************************/
662 /** @ingroup cb_rsa
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.
672 * @par Externals
673 * None
675 * @return
676 * number of commands necessary
678 * @par Errors
679 * None
681 * @par Assumptions
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;
693 else
695 ret = NOT_USING_SKS_NUM_COMMANDS;
697 return ret;
698 } /* cb_RSADecryptOperations */