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