1/*-
2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
3 * All rights reserved.
4 *
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:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 *
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.
21 *
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.
33 */
34
35static char const n8_id[] = "$Id: n8_cb_pk_ops.c,v 1.1 2008/10/30 12:02:15 darran Exp $";
36/*****************************************************************************/
37/** @file n8_cb_pk_ops.c
38 *  @brief PKP Operations
39 *
40 * Command block generation for individual PKP operations
41 *
42 *****************************************************************************/
43
44/*****************************************************************************
45 * Revision history:
46 * 09/10/02 brr   Set command complete bit on last command block.
47 * 05/20/02 bac   Corrected calculation of number of commands generated.
48 * 05/07/02 bac   Original version.
49 ****************************************************************************/
50/** @defgroup cb_pkp PKP Operations
51 */
52
53#include "n8_cb_pk_ops.h"
54#include "n8_pk_common.h"
55#include "n8_util.h"
56
57/*****************************************************************************
58 * cb_pk_op
59 *****************************************************************************/
60/** @ingroup cb_pkp
61 * @brief Perform generic PKP math for two operand operations
62 *
63 * For operations of the form:
64 * result = R mod n, or
65 * result = a mod n, or
66 * result = a (op) b mod n
67 *
68 *  @param req_p               RW:  Pointer to API request structure
69 *  @param shifted_opcode      RO:  Opcode to use, pre-shifted to the left for
70 *                                  direct insertion into the command block
71 *  @param a_a                 RO:  "a" operand physical address
72 *  @param a_length_bytes      RO:  Length of "a"
73 *  @param b_a                 RO:  "b" operand physical address
74 *  @param b_length_bytes      RO:  Length of "b"
75 *  @param modulus_a           RO:  modulus operand physical address
76 *  @param mod_length_bytes    RO:  Length of modulus
77 *  @param max_length_bytes    RO:  Max length of operands or modulus
78 *  @param result_a            RW:  results buffer physical address
79 *  @param cb_p                RW:  Pointer to command block
80 *  @param next_cb_pp          RW:  Returned pointer to next command block.  May
81 *                                  be NULL
82 *
83 * @par Externals
84 *    None
85 *
86 * @return
87 *    Status.  N8_STATUS_OK on success
88 *
89 * @par Errors
90 *    None
91 *
92 * @par Assumptions
93 *    None
94 *****************************************************************************/
95N8_Status_t cb_pk_op(API_Request_t     *req_p,
96                     const uint32_t     shifted_opcode,
97                     const uint32_t     a_a,
98                     const unsigned int a_length_bytes,
99                     const uint32_t     b_a,
100                     const unsigned int b_length_bytes,
101                     const uint32_t     modulus_a,
102                     const unsigned int mod_length_bytes,
103                     const unsigned int max_length_bytes,
104                     const uint32_t     result_a,
105                     PK_CMD_BLOCK_t    *cb_p,
106                     PK_CMD_BLOCK_t   **next_cb_pp)
107{
108   N8_Status_t ret = N8_STATUS_OK;
109   PK_CMD_BLOCK_t         *math_wr_ptr;
110   PK_LDST_CMD_BLOCK_t    *ldst_wr_ptr;
111   uint32_t max_length_digits = BYTES_TO_PKDIGITS(max_length_bytes);
112   uint32_t mod_length_digits = BYTES_TO_PKDIGITS(mod_length_bytes);
113   uint32_t a_length_digits   = BYTES_TO_PKDIGITS(a_length_bytes);
114   uint32_t b_length_digits   = BYTES_TO_PKDIGITS(b_length_bytes);
115   uint32_t offset[4];
116   unsigned int i;
117   unsigned int numCommands = N8_CB_PK_OP_NUMCMDS; /* set to maximum and
118                                                    * decrement if commands are
119                                                    * skipped.  */
120   do
121   {
122      for (i = 0; i < sizeof(offset)/sizeof(uint32_t); i++)
123      {
124         offset[i] = i * max_length_digits;
125      } /* for i */
126
127      /* initialize the load/store pointer to the begining of the
128       * command block */
129      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) cb_p;
130
131      /* load a to 0, if non-zero*/
132      if (a_length_bytes != 0)
133      {
134         ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
135         ldst_wr_ptr->r_offset = offset[0];
136         ldst_wr_ptr->data_addr_ls = a_a;
137         ldst_wr_ptr->data_length = a_length_bytes;
138         ldst_wr_ptr++;
139      }
140      else
141      {
142         numCommands--;
143      }
144
145      /* load b to 1*/
146      if (b_length_bytes != 0)
147      {
148         ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
149         ldst_wr_ptr->r_offset = offset[1];
150         ldst_wr_ptr->data_addr_ls = b_a;
151         ldst_wr_ptr->data_length = b_length_bytes;
152         ldst_wr_ptr++;
153      }
154      else
155      {
156         numCommands--;
157      }
158
159      /* load modulus to 2 */
160      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
161      ldst_wr_ptr->r_offset = offset[2];
162      ldst_wr_ptr->data_addr_ls = modulus_a;
163      ldst_wr_ptr->data_length = mod_length_bytes;
164
165      /* perform operation with results going to 3 */
166      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
167      math_wr_ptr->opcode_si = shifted_opcode;
168      math_wr_ptr->a_length_offset =
169         (a_length_digits << PK_Cmd_Length_Shift) | offset[0];
170      math_wr_ptr->b_length_offset =
171         (b_length_digits << PK_Cmd_Length_Shift) | offset[1];
172      math_wr_ptr->m_length_offset =
173         (mod_length_digits << PK_Cmd_Length_Shift) | offset[2];
174      math_wr_ptr->r_offset = offset[3];
175
176      /* store results */
177      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
178      ldst_wr_ptr->opcode_si = PK_Cmd_Store_R | PK_Cmd_SI_Mask;
179      ldst_wr_ptr->r_offset = offset[3];
180      ldst_wr_ptr->data_addr_ls = result_a;
181      ldst_wr_ptr->data_length = mod_length_bytes;
182
183      /* save next address for future use */
184      if (next_cb_pp != NULL)
185      {
186         *next_cb_pp = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
187      }
188
189      DBG_PRINT_PK_CMD_BLOCKS("pk operation",
190                              cb_p,
191                              numCommands);
192
193   } while (N8_FALSE);
194
195   return ret;
196} /* cb_pk_op */
197