source: svn/trunk/newcon3bcm2_21bu/nexus/modules/security/7552/src/nexus_security.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 87.6 KB
Line 
1/***************************************************************************
2 *     (c)2007-2011 Broadcom Corporation
3 *
4 *  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 *  and may only be used, duplicated, modified or distributed pursuant to the terms and
6 *  conditions of a separate, written license agreement executed between you and Broadcom
7 *  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 *  no license (express or implied), right to use, or waiver of any kind with respect to the
9 *  Software, and Broadcom expressly reserves all rights in and to the Software and all
10 *  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 *  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 *  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 *  Except as expressly set forth in the Authorized License,
15 *
16 *  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 *  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 *  and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 *  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 *  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 *  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 *  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 *  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 *  USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 *  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 *  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 *  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 *  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 *  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 *  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 *  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 *  ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: nexus_security.c $
39 * $brcm_Revision: 97 $
40 * $brcm_Date: 11/30/11 2:18p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/security/7400/src/nexus_security.c $
47 *
48 * 97   11/30/11 2:18p atruong
49 * SW7425-1753: Accommodate new settings for 40-nm B1
50 *
51 * 96   11/23/11 4:04p jtna
52 * SW7425-1708: add s3 power management for security
53 *
54 * 95   11/7/11 11:51a atruong
55 * SWSECURITY-53: Code maintenace - SC Values only for CA.
56 *
57 * 94   11/3/11 5:40p mward
58 * SW7435-7:  Add 7435.
59 *
60 * 93   10/31/11 3:33p mphillip
61 * SW7344-208: Guarded bConfigClear so that only non-40nm platforms will
62 *  see it (fixes a coverity warning on 40nm platforms)
63 *
64 * 92   10/17/11 5:37p atruong
65 * SWSECURITY-69: Support for 40-nm B0 Zeus 2.0 platforms
66 *
67 * 91   10/13/11 10:31a mphillip
68 * SW7346-481: Guard SC value variable
69 *
70 * 90   10/12/11 12:37p mphillip
71 * SW7346-481: Merge B0 changes to main
72 *
73 * SW7346-481/2   9/9/11 7:13p mphillip
74 * SW7346-481: Add bRestrictSourceDropPktEnable for HSM's
75 *  bDropRregionPackets
76 *
77 * SW7346-481/1   9/9/11 6:28p mphillip
78 * SW7346-481: Initial 7346 B0 and 7425 B0 support
79 *
80 * 89   9/22/11 9:58a atruong
81 * SW7346-495: Nexus NSK2AVK extension module support - code cleanup
82 *
83 * 88   9/21/11 1:39p atruong
84 * SW7346-495: Add NSK2AVK support
85 *
86 * 87   9/9/11 5:49p mphillip
87 * SW7346-481: Add default ASKM configuration
88 *
89 * 86   8/9/11 3:09p mphillip
90 * SW7425-1041: Add missing keydestblock to 40nm config algorithm
91 *
92 * 85   8/3/11 11:09a gmohile
93 * SW7125-1014 : Add module to active priority scheduler
94 *
95 * 84   7/13/11 5:29p atruong
96 * SW7231-272: CPD and CPS Support only for ASKM platforms
97 *
98 * 83   7/13/11 3:33p atruong
99 * SW7231-272: CPD and CPS Support only for ASKM platforms
100 *
101 * 82   7/12/11 1:14a atruong
102 * SW7231-272: Code Cleanup to include CPD and CPS support
103 *
104 * 81   7/7/11 11:41a mphillip
105 * SW7358-56: Correct the keydest block for m2m keyslots
106 *
107 * 80   7/6/11 11:55a atruong
108 * SW7425-812: Fixed compile/runtime error for heap pointer supporting 40-
109 *  nm HMAC-SHA
110 *
111 * 79   6/30/11 2:57p atruong
112 * SW7425-812:HSM PI API modification for new HMAC-SHA support
113 *
114 * 78   6/30/11 2:49a atruong
115 * SW7552-41: Nexus Security Support For BCM7552 A0
116 *
117 * 77   6/21/11 4:12p bselva
118 * SW7358-50:Enable Nexus security support for 7358 platform
119 *
120 * 77   6/21/11 4:08p bselva
121 * SW7358-50:Enable Nexus security support for 7358 platform
122 *
123 * 76   6/20/11 3:38p mphillip
124 * SW7422-253: Fix pre-ASKM build error
125 *
126 * 75   6/15/11 7:35p mphillip
127 * SW7422-253: Remove extraneous debug statements from previous commit
128 *
129 * 74   6/15/11 7:28p mphillip
130 * SW7422-253: Bring 7420 SC bit implementation in line with 7422
131 *  implementation
132 *
133 * 73   5/9/11 6:55p mphillip
134 * SW7422-430: Merge API change to main
135 *
136 * 72   5/3/11 4:09p mward
137 * SW7125-905: SW7420-1412:  Power on HSM during
138 *  NEXUS_Security_P_InitHsm().
139 *
140 * SW7422-430/2   5/2/11 11:21a mphillip
141 * SW7422-430: Provide for separate odd/even CA configuration while still
142 *  defaulting to configuring both
143 *
144 * SW7422-430/1   4/25/11 11:57a mphillip
145 * SW7422-430: Refactor key-type selection, allow user to specify which
146 *  keyslot type is allocated
147 *
148 * 71   3/25/11 5:01p mphillip
149 * SW7420-1736: Only update nexus-level keyslot tracking when overwriting
150 *  a pidchannel/keyslot association
151 *
152 * 70   3/17/11 5:19p mphillip
153 * SW7420-1495: Add algorithm tracking for aes destination block
154 *  differentiation
155 *
156 * 69   3/17/11 4:53p mphillip
157 * SW7422-335: Merge API change to main
158 *
159 * SW7422-335/1   3/10/11 5:05p mphillip
160 * SW7422-335: Update key2select for 40nm
161 *
162 * 68   3/10/11 3:52p mphillip
163 * SW7422-269: Merge changes to main
164 *
165 * 67   3/9/11 7:03p mphillip
166 * SW7400-2948: Internal pidchannel/keyslot tracking to fix memory leaks
167 *  and ensure keyslots are properly freed and associations are broken
168 *
169 * SW7422-269/3   3/9/11 5:09p mphillip
170 * SW7422-264: Update per-key IV datatype name.
171 *
172 * SW7422-269/1   3/3/11 4:57p mphillip
173 * SW7422-269: Preliminary IV handling
174 *
175 * 66   2/24/11 3:57p mphillip
176 * SW7422-104: Cleanup destination block logic
177 *
178 * 65   2/23/11 7:46p mphillip
179 * SW7422-104: Update SC bit handling and destination block handling
180 *
181 * 64   2/23/11 11:14a mphillip
182 * SW7422-253: Merge API changes to main
183 *
184 * SW7422-253/2   2/16/11 7:41p mphillip
185 * SW7422-253: Allow SC bits to be controlled per-packet-type
186 *
187 * SW7422-253/1   2/15/11 7:55p mphillip
188 * SW7422-253: Update 7422 support for building with BSP_SC_VALUE_SUPPORT
189 *
190 * 63   2/16/11 11:09p hongtaoz
191 * SW7425-103: add security support for 7425;
192 *
193 * 62   2/2/11 4:11p jrubio
194 * SW7346-19: add 7346/7344
195 *
196 * 61   1/21/11 6:10p katrep
197 * SW7231-7:add support for 7231
198 *
199 * 60   1/21/11 2:19p yili
200 * SW7405-4221:Add support for new applications
201 *
202 * 59   1/19/11 12:16p mphillip
203 * SW7420-1374: Update targets for 7420/7422 Ca, Cp, and CaCp operations
204 *
205 * 58   1/3/11 11:00a atruong
206 * SW7422-104: Compilation bug fix - setMiscBitsIO members
207 *
208 * 57   12/30/10 1:53p atruong
209 * SW7422-104: Graceful handling of unprogrammed chips (blank OTP)
210 *
211 * 57   12/30/10 1:36p atruong
212 * SW7422-104: Graceful handling of unprogrammed chips (blank OTP)
213 *
214 * 56   12/23/10 10:48a mphillip
215 * SW7422-104: Fix the algorithm mapping for non-40nm ASKM HSM
216 *
217 * 55   12/22/10 5:48p mphillip
218 * SW7422-104: Merge 40nm support to /main
219 *
220 * SW7422-104/3   12/22/10 5:34p mphillip
221 * SW7422-104: 7422 extended data handled
222 *
223 * SW7422-104/2   12/22/10 11:41a mphillip
224 * SW7422-104: Structure updates/fixups
225 *
226 * SW7422-104/1   12/16/10 6:14p mphillip
227 * SW7422-104: Initial support for 7422
228 *
229 * 54   11/4/10 5:13p mphillip
230 * SW7400-2948: Switch all BCHP_CHIP defines to feature defines for better
231 *  and more centralized control
232 *
233 * 53   10/20/10 2:09p mphillip
234 * SW7400-2948: Add debug messages to track keyslot associations
235 *
236 * 52   8/6/10 4:39p mphillip
237 * SW7405-4325: Destroy keyslot debug object in core, not security
238 *
239 * 51   8/4/10 3:04p mphillip
240 * SW7405-4325: Merge keyslot refactoring to main
241 *
242 * SW7405-4325/2   8/4/10 2:31p mphillip
243 * SW7405-4325: Move keyslot memory management into core
244 *
245 * SW7405-4325/1   7/2/10 7:23p mphillip
246 * SW7405-4325: Move keyslot allocation/deallocation to base to break DMA
247 *  dependency
248 *
249 * 50   6/30/10 6:03p mphillip
250 * SW7550-415: Error cleanup, memory management cleanup, keyslot debug
251 *  object additions
252 *
253 * 49   6/23/10 2:01p mphillip
254 * SW7550-415: Whitespace/formatting clean-up in preparation for other
255 *  code cleanup
256 *
257 * 48   5/10/10 11:04a erickson
258 * SW7550-415: add NEXUS_Security_GetDefaultClearKey
259 *
260 * 47   4/21/10 3:44p yili
261 * SW7420-457:External IV support
262 *
263 * 46   3/16/10 11:23a atruong
264 * SW7400-2678: Fixed parameter naming for InvalidateKey function
265 *
266 * 45   3/15/10 12:14p atruong
267 * SW7400-2678: Nexus AV Keyladder to support DirecTV
268 *
269 * 44   3/14/10 11:44p atruong
270 * SW7400-2678: Nexus AV Keyladder to support DirecTV
271 *
272 * 43   2/3/10 11:39a yili
273 * SW7420-457:Add SC moidfication support for clear packet
274 *
275 * 42   12/14/09 4:35p atruong
276 * SW7468-16: Support For 7468A0 - bug fix
277 *
278 * 41   12/9/09 5:01p atruong
279 * SW7468-16: Support For 7468A0
280 *
281 * 40   11/18/09 2:55p yili
282 * SW7340-42:Remove region verification code
283 *
284 * 39   10/27/09 2:38p yili
285 * SW7340-42:minor change
286 *
287 * 38   10/27/09 2:29p yili
288 * SW7340-42:Added region verification
289 *
290 * 37   9/10/09 1:50p mward
291 * SW7420-223: Initialize residualMode to prevent compiler warning.
292 *
293 * 36   8/25/09 1:09a atruong
294 * SW7420-223: 7420B0 ASKM Support
295 *
296 * 35   8/21/09 3:45p mward
297 * PR55545: Adding 7125.
298 *
299 * 34   8/12/09 3:41p atruong
300 * PR55169: Support for 7420B0 ASKM
301 *
302 * 33   7/10/09 6:06p atruong
303 * PR55169: NEXUS/HSM PI support for 7420A1
304 *
305 * 32   4/29/09 10:25a yili
306 * PR53745:Fixed compiler warning
307 *
308 * 31   4/28/09 12:12p yili
309 * PR53745:Minor bug fix.
310 *
311 * 30   4/27/09 2:14p yili
312 * PR53745: Allow users to configure CA/CP key slot settings for Nexus
313 *  security.
314 *
315 * 29   4/15/09 12:02p yili
316 * PR53745:Add nexus security sample code
317 *
318 * 28   4/13/09 4:43p katrep
319 * PR53733: MSDRM PD HW DECRYPT
320 *
321 * 27   4/2/09 11:36a mphillip
322 * PR53809: Enable AES for 3548/3556 CA
323 *
324 * 26   4/1/09 3:18p katrep
325 * PR53733: Fixed compilation issue when MSDRM_PD_SUPPORT is not enabled
326 *
327 * 25   4/1/09 1:20p katrep
328 * PR53733: Added security algorithm type for MSDRM PD HGW DECRYPT
329 *
330 * 24   3/18/09 11:25a mphillip
331 * PR53355: Free handle when freeing keyslot
332 *
333 * 23   3/10/09 8:50p mphillip
334 * PR52786: Let power management know the hsm core should be powered on
335 *  when keys have been allocated
336 *
337 * 22   3/9/09 12:15p mphillip
338 * PR52786: Add timestamp support for keyslot configuration
339 *
340 * 21   1/27/09 11:29a erickson
341 * PR50367: add memset after malloc of handle
342 *
343 * 20   1/7/09 2:46p mphillip
344 * PR50093: Add Multi2 support
345 *
346 * 19   9/9/08 11:49a mphillip
347 * PR44933: Clarify keyslot allocation to avoid multiple allocations on
348 *  m2m
349 *
350 * 18   9/3/08 3:29p erickson
351 * PR45612: update
352 *
353 * 17   8/20/08 11:28a mphillip
354 * PR45884: Add Remux support
355 *
356 * 16   7/23/08 11:25a mphillip
357 * PR45072: Fix switch conditional (thanks, Coverity!)
358 *
359 * 15   7/14/08 3:31p mphillip
360 * PR44795: Accommodate type redefinition
361 *
362 * 14   6/24/08 4:57p vsilyaev
363 * PR 40027: Added security module to 93556/93549 platform
364 *
365 * 13   6/24/08 11:51a mphillip
366 * PR40027: Re-enable m2m key slot allocation
367 *
368 * 12   6/23/08 6:15p mphillip
369 * PR40027: Tidy up naming conventions to match with Nexus
370 *
371 * 11   6/17/08 6:16p mphillip
372 * PR40027: Retrieve more information from KeySlotHandle
373 *
374 * 10   6/17/08 12:33a mphillip
375 * PR40027: Keyslot changes for shim
376 *
377 * 9   5/29/08 10:52a mphillip
378 * PR38369: Add work-around for DTV chips missing some enums
379 *
380 * 8   5/28/08 2:32p mphillip
381 * PR38369: Refactor keyslot configuration to Security module from Crypto
382 *  module
383 *
384 * 7   5/27/08 5:05p erickson
385 * PR34925: added b_get_reg, b_get_int and b_get_chp
386 *
387 * 6   5/22/08 3:31p erickson
388 * PR34925: add b_get_hsm for debug
389 *
390 * 5   5/12/08 4:41p erickson
391 * PR42628: call BHSM_Channel_Close when closing the module
392 *
393 * 4   5/6/08 4:44p erickson
394 * PR39453: remove BHSM_SetMiscBitsIO_t for 3548/3556 as instructed
395 *
396 * 3   3/31/08 1:41p erickson
397 * PR41077: added NEXUS_ASSERT_MODULE to _priv function
398 *
399 * 2   2/29/08 11:04a erickson
400 * PR37137: create stub to remove sync thunk warning
401 *
402 * 1   1/18/08 2:21p jgarrett
403 * PR 38808: Merging to main branch
404 *
405 * Nexus_Devel/2   11/15/07 4:01p erickson
406 * PR37137: security update
407 *
408 * Nexus_Devel/1   11/15/07 3:54p erickson
409 * PR37137: added Security module
410 *
411 **************************************************************************/
412#include "nexus_security_module.h"
413#include "nexus_security_datatypes.h"
414#include "nexus_security.h"
415#include "priv/nexus_security_priv.h"
416#include "priv/nexus_core.h"
417#include "priv/nexus_security_standby_priv.h"
418
419#include "nexus_power_management.h"
420
421#include "bhsm.h"
422#include "bsp_s_commands.h"
423#include "bsp_s_misc.h"
424#include "bsp_s_hw.h"
425#include "bsp_s_keycommon.h"
426#include "bhsm_keyladder.h"
427
428#include "nexus_base.h"
429
430BDBG_MODULE(nexus_security);
431
432/* Feature defines.  There should be NO #if BCHP_CHIP macros controlling features.
433 * Instead, maintain the chip/version list here, and switch features via these defines. */
434
435
436/* DigitalTV chip like 3563 has only ONE HSM channel, no cancel cmd support */
437#if (BCHP_CHIP!=3563)
438#define HAS_TWO_HSM_CMD_CHANNELS 1
439#endif
440
441/* This define controls whether to include the AES, CSS, and C2 remapping in the functions.
442 * The 3563 and 3548/3556 HSM PI has commented certain enums out, which has a ripple effect
443 * in generic code. */
444#if (BCHP_CHIP != 3563) && (BCHP_CHIP != 3548) && (BCHP_CHIP != 3556)
445#define SUPPORT_NON_DTV_CRYPTO 1
446#endif
447
448/* A change requires AES to be broken out for these chips */
449#if (BCHP_CHIP == 3548) || (BCHP_CHIP == 3556)
450#define SUPPORT_AES_FOR_DTV 1
451#endif
452
453#if (BCHP_CHIP!=3563) && (BCHP_CHIP!=3548) && (BCHP_CHIP!=3556) && (BCHP_CHIP!=7422) && \
454     (BCHP_CHIP!=7425) && (BCHP_CHIP!=7231) && (BCHP_CHIP!=7344) && (BCHP_CHIP!=7346) && \
455     (BCHP_CHIP!=7358) && (BCHP_CHIP!=7552) && (BCHP_CHIP!=7435)
456#define SET_MISC_BITS 1
457#endif
458
459#if ((BCHP_CHIP == 7420) && (BCHP_VER >= BCHP_VER_A1)) || (BCHP_CHIP == 7340) || \
460     (BCHP_CHIP == 7342) || (BCHP_CHIP == 7125) || (BCHP_CHIP == 7468)
461#define HAS_TYPE7_KEYSLOTS 1
462#endif
463
464#if ((BCHP_CHIP == 7420) && (BCHP_VER >= BCHP_VER_A1)) || (BCHP_CHIP == 7340) || \
465     (BCHP_CHIP == 7342) || (BCHP_CHIP == 7125) || (BCHP_CHIP == 7468) || (BCHP_CHIP == 7346) || \
466     (BCHP_CHIP == 7422) || (BCHP_CHIP == 7425) || (BCHP_CHIP == 7231) || (BCHP_CHIP == 7344) || \
467     (BCHP_CHIP == 7358) || (BCHP_CHIP == 7552) || (BCHP_CHIP == 7435)
468#define HSM_IS_ASKM 1
469#endif
470
471#if !HSM_IS_ASKM_40NM
472#define HAS_TYPE5_KEYSLOTS 1
473#include "bhsm_misc.h"
474#endif
475
476#define MAKE_HSM_ERR(x) (NEXUS_SECURITY_HSM_ERROR | x)
477
478#include "blst_slist.h"
479typedef struct NEXUS_Security_P_PidChannelListNode {
480    BLST_S_ENTRY(NEXUS_Security_P_PidChannelListNode) next;
481    unsigned long pidchannel;
482} NEXUS_Security_P_PidChannelListNode;
483BLST_S_HEAD(NEXUS_Security_P_PidChannelList_t, NEXUS_Security_P_PidChannelListNode);
484
485typedef struct NEXUS_Security_P_KeySlotListNode {
486    BLST_S_ENTRY(NEXUS_Security_P_KeySlotListNode) next;
487    NEXUS_KeySlotHandle handle;
488    struct NEXUS_Security_P_PidChannelList_t pidchannels;
489    NEXUS_SecurityAlgorithm algorithm;
490} NEXUS_Security_P_KeySlotListNode;
491
492BLST_S_HEAD(NEXUS_Security_P_KeySlotList_t, NEXUS_Security_P_KeySlotListNode);
493
494#if 0
495#define NEXUS_SECURITY_DUMP_KEYSLOTS \
496    { \
497        NEXUS_Security_P_KeySlotListNode *p; \
498        for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) { \
499            NEXUS_Security_P_PidChannelListNode *q; \
500            BDBG_MSG(("%s: Keyslot [%p]",__FUNCTION__,p->handle)); \
501            for (q=BLST_S_FIRST(&p->pidchannels);q!=NULL;q=BLST_S_NEXT(q,next)) { \
502                BDBG_MSG(("%s:   keyslot [%p] has pidchannel [%d]",__FUNCTION__,p->handle,q->pidchannel)); \
503            } \
504            BDBG_MSG(("%s: end of Keyslot [%p]",__FUNCTION__,p->handle)); \
505        } \
506    }
507#else
508#define NEXUS_SECURITY_DUMP_KEYSLOTS
509#endif
510
511NEXUS_ModuleHandle NEXUS_P_SecurityModule = NULL;
512static struct {
513    NEXUS_SecurityModuleSettings settings;
514    BHSM_Handle hsm;
515    BHSM_ChannelHandle hsmChannel[BHSM_HwModule_eMax];
516    struct NEXUS_Security_P_KeySlotList_t keyslots;
517} g_security;
518
519static BERR_Code NEXUS_Security_P_InitHsm(const NEXUS_SecurityModuleSettings * pSettings);
520static void NEXUS_Security_P_UninitHsm(void);
521
522
523/*
524 * Helper functions
525 */
526static NEXUS_Security_P_KeySlotListNode *NEXUS_Security_P_LocateNodeByKeyslot(NEXUS_KeySlotHandle keyHandle)
527{
528    NEXUS_Security_P_KeySlotListNode *p = NULL;
529
530    for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
531        if (p->handle == keyHandle)
532            break;
533    }
534
535    return p;
536}
537
538static void NEXUS_Security_P_RemovePidchannel(NEXUS_Security_P_KeySlotListNode *p, NEXUS_Security_P_PidChannelListNode *q) {
539    BLST_S_REMOVE(&p->pidchannels,q,NEXUS_Security_P_PidChannelListNode,next);
540    BKNI_Free(q);
541}
542
543/****************************************
544 * Module functions
545 ****************************************/
546
547
548
549void NEXUS_SecurityModule_GetDefaultSettings(NEXUS_SecurityModuleSettings *pSettings)
550{
551    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
552#if HSM_IS_ASKM_40NM
553    pSettings->numKeySlotsForType[0] = 10;
554    pSettings->numKeySlotsForType[1] = 7;
555    pSettings->numKeySlotsForType[2] = 11;
556    pSettings->numKeySlotsForType[3] = 5;
557    pSettings->numKeySlotsForType[4] = 6;
558#else
559    pSettings->numKeySlotsForType[0] = 10;
560    pSettings->numKeySlotsForType[1] = 7;
561    pSettings->numKeySlotsForType[2] = 11;
562    pSettings->numKeySlotsForType[3] = 5;
563    pSettings->numKeySlotsForType[4] = 6;
564    pSettings->numKeySlotsForType[5] = 2;
565    pSettings->numKeySlotsForType[6] = 8;
566#if HAS_TYPE7_KEYSLOTS
567    pSettings->numKeySlotsForType[7] = 4;
568#endif
569#endif
570
571}
572
573NEXUS_ModuleHandle NEXUS_SecurityModule_Init(const NEXUS_SecurityModuleSettings *pSettings)
574{
575    NEXUS_ModuleSettings moduleSettings;
576    NEXUS_SecurityModuleSettings defaultSettings;
577    BERR_Code rc;
578
579    BDBG_ASSERT(!NEXUS_P_SecurityModule);
580
581    if (!pSettings) {
582        NEXUS_SecurityModule_GetDefaultSettings(&defaultSettings);
583        pSettings = &defaultSettings;
584    }
585
586    /* init global module handle */
587    NEXUS_Module_GetDefaultSettings(&moduleSettings);
588    moduleSettings.priority = NEXUS_ModulePriority_eLowActiveStandby;
589    NEXUS_P_SecurityModule = NEXUS_Module_Create("security", &moduleSettings);
590    if (!NEXUS_P_SecurityModule) {
591        return NULL;
592    }
593
594    g_security.settings = *pSettings;
595
596    rc = NEXUS_Security_P_InitHsm(pSettings);
597    if (rc) {
598        NEXUS_Module_Destroy(NEXUS_P_SecurityModule);
599        NEXUS_P_SecurityModule = NULL;
600    } else {
601        BLST_S_INIT(&g_security.keyslots);
602    }
603    return NEXUS_P_SecurityModule;
604}
605
606void NEXUS_SecurityModule_GetCurrentSettings(NEXUS_ModuleHandle module, NEXUS_SecurityModuleSettings *pSettings)
607{
608    BDBG_ASSERT(pSettings);
609    BDBG_ASSERT(module);
610    *pSettings = g_security.settings;
611}
612
613
614void NEXUS_SecurityModule_Uninit()
615{
616    NEXUS_SECURITY_DUMP_KEYSLOTS;
617    while (NULL != BLST_S_FIRST(&g_security.keyslots)) {
618        NEXUS_Security_P_KeySlotListNode *p;
619        p=BLST_S_FIRST(&g_security.keyslots);
620        BDBG_WRN(("Keyslot %p was not freed, freeing",p->handle));
621        NEXUS_Security_FreeKeySlot(p->handle);
622    }
623    NEXUS_Security_P_UninitHsm();
624    NEXUS_Module_Destroy(NEXUS_P_SecurityModule);
625    NEXUS_P_SecurityModule = NULL;
626}
627
628static BERR_Code NEXUS_Security_P_InitHsm(const NEXUS_SecurityModuleSettings * pSettings)
629{
630    BHSM_Settings hsmSettings;
631    BHSM_ChannelSettings hsmChnlSetting;
632    BHSM_InitKeySlotIO_t keyslot_io;
633    BERR_Code rc;
634
635    NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, true);
636
637    BHSM_GetDefaultSettings(&hsmSettings, g_pCoreHandles->chp);
638#if HSM_IS_ASKM_40NM
639    hsmSettings.hHeap = g_pCoreHandles->heap[0];
640#endif
641    rc = BHSM_Open(&g_security.hsm, g_pCoreHandles->reg, g_pCoreHandles->chp, g_pCoreHandles->bint, &hsmSettings);
642    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
643
644    rc = BHSM_GetChannelDefaultSettings(g_security.hsm, BHSM_HwModule_eCmdInterface1, &hsmChnlSetting);
645    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
646
647#if HAS_TWO_HSM_CMD_CHANNELS
648    rc = BHSM_Channel_Open(g_security.hsm, &g_security.hsmChannel[BHSM_HwModule_eCmdInterface1], BHSM_HwModule_eCmdInterface1, &hsmChnlSetting);
649    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
650#endif
651
652    rc = BHSM_Channel_Open(g_security.hsm, &g_security.hsmChannel[BHSM_HwModule_eCmdInterface2], BHSM_HwModule_eCmdInterface2, &hsmChnlSetting);
653    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
654
655    BKNI_Memset(&keyslot_io, 0, sizeof(keyslot_io));
656
657    keyslot_io.unKeySlotType0Num = pSettings->numKeySlotsForType[0];
658    keyslot_io.unKeySlotType1Num = pSettings->numKeySlotsForType[1];
659    keyslot_io.unKeySlotType2Num = pSettings->numKeySlotsForType[2];
660    keyslot_io.unKeySlotType3Num = pSettings->numKeySlotsForType[3];
661    keyslot_io.unKeySlotType4Num = pSettings->numKeySlotsForType[4];
662#if HAS_TYPE5_KEYSLOTS
663    keyslot_io.unKeySlotType5Num = pSettings->numKeySlotsForType[5];
664    keyslot_io.unKeySlotType6Num = pSettings->numKeySlotsForType[6];
665#if HAS_TYPE7_KEYSLOTS
666    keyslot_io.unKeySlotType7Num = pSettings->numKeySlotsForType[7];
667#endif
668#endif
669#if HSM_IS_ASKM_40NM
670    keyslot_io.bConfigMulti2KeySlot = pSettings->enableMulti2Key;
671#endif
672    /* Disregard errors, as this can only be run once per board boot. */
673    rc = BHSM_InitKeySlot(g_security.hsm, &keyslot_io);
674    /* Print out warning and ignore the error */
675    if (rc)
676    {
677        BDBG_WRN(("**********************************************"));
678        BDBG_WRN(("If you see this warning and the HSM errors above, you need to perform some"));
679        BDBG_WRN(("board reconfiguration. This is not required. If you want, you can ignore them."));
680        BDBG_WRN(("Use BBS to check if BSP_GLB_NONSECURE_GLB_IRDY = 0x07."));
681        BDBG_WRN(("If not, BSP/Aegis is not ready to accept a command."));
682        BDBG_WRN(("SUN_TOP_CTRL_STRAP_VALUE[bit28:29 strap_test_debug_en] should be 0b'00 if you plan"));
683        BDBG_WRN(("to use BSP ROM code. If not, check with board designer on your strap pin."));
684        BDBG_WRN(("**********************************************"));
685        rc = BERR_SUCCESS;
686    }
687
688#if SET_MISC_BITS
689    {
690        BHSM_SetMiscBitsIO_t setMiscBitsIO;
691
692        setMiscBitsIO.setMiscBitsSubCmd = BCMD_SetMiscBitsSubCmd_eRaveBits;
693        setMiscBitsIO.bEnableWriteIMem = 1;
694        setMiscBitsIO.bEnableReadIMem = 1;
695        setMiscBitsIO.bEnableReadDMem = 1;
696        setMiscBitsIO.bDisableClear = 1;
697#if HSM_IS_ASKM_40NM
698        setMiscBitsIO.bRAVEEncryptionBypass = 0;
699#else
700        setMiscBitsIO.bEnableEncBypass = 0;
701#endif
702        rc = BHSM_SetMiscBits(g_security.hsm, &setMiscBitsIO);
703        if (rc) {
704            BDBG_WRN(("**********************************************"));
705            BDBG_WRN(("If you see this warning and the HSM errors above, you need to perform some"));
706            BDBG_WRN(("board reconfiguration. This is not required. If you want, you can ignore them."));
707            BDBG_WRN(("Use BBS to check if BSP_GLB_NONSECURE_GLB_IRDY = 0x07."));
708            BDBG_WRN(("If not, BSP/Aegis is not ready to accept a command."));
709            BDBG_WRN(("SUN_TOP_CTRL_STRAP_VALUE[bit28:29 strap_test_debug_en] should be 0b'00 if you plan"));
710            BDBG_WRN(("to use BSP ROM code. If not, check with board designer on your strap pin."));
711            BDBG_WRN(("**********************************************"));
712            rc = BERR_SUCCESS;
713        }
714    }
715#endif
716    NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, false);
717
718    return rc;
719}
720
721void NEXUS_Security_P_UninitHsm()
722{
723#if HAS_TWO_HSM_CMD_CHANNELS
724    (void)BHSM_Channel_Close(g_security.hsmChannel[BHSM_HwModule_eCmdInterface1]);
725#endif
726    (void)BHSM_Channel_Close(g_security.hsmChannel[BHSM_HwModule_eCmdInterface2]);
727    BHSM_Close(g_security.hsm);
728}
729
730void NEXUS_Security_GetHsm_priv(BHSM_Handle *pHsm)
731{
732    NEXUS_ASSERT_MODULE();
733    *pHsm = g_security.hsm;
734}
735
736void NEXUS_Security_GetDefaultKeySlotSettings(NEXUS_SecurityKeySlotSettings *pSettings)
737{
738    if (pSettings) {
739        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
740        pSettings->keySlotEngine = NEXUS_SecurityEngine_eCa;
741#if HSM_IS_ASKM
742        pSettings->keySlotSource = NEXUS_SecurityKeySource_eFirstRamAskm;
743#else
744        pSettings->keySlotSource = NEXUS_SecurityKeySource_eFirstRam;
745#endif
746        pSettings->keySlotType = NEXUS_SecurityKeySlotType_eAuto;
747    }
748}
749
750void NEXUS_Security_GetKeySlotInfo(NEXUS_KeySlotHandle keyHandle, NEXUS_SecurityKeySlotInfo *pKeyslotInfo)
751{
752    NEXUS_P_Core_GetKeySlotInfo(keyHandle, pKeyslotInfo);
753}
754
755static BCMD_KeyDestEntryType_e NEXUS_Security_MapNexusKeyDestToHsm(NEXUS_KeySlotHandle keyHandle, NEXUS_SecurityKeyType keydest)
756{
757    BCMD_KeyDestEntryType_e rv = BCMD_KeyDestEntryType_eOddKey;
758    BSTD_UNUSED(keyHandle);
759    switch (keydest) {
760    case NEXUS_SecurityKeyType_eOddAndEven:
761    case NEXUS_SecurityKeyType_eOdd:
762        rv = BCMD_KeyDestEntryType_eOddKey;
763        break;
764    case NEXUS_SecurityKeyType_eEven:
765        rv = BCMD_KeyDestEntryType_eEvenKey;
766        break;
767    case NEXUS_SecurityKeyType_eClear:
768#if HSM_IS_ASKM_40NM
769        rv = BCMD_KeyDestEntryType_eReserved2;
770#else
771        rv = BCMD_KeyDestEntryType_eReserved0;
772#endif
773        break;
774#if !HSM_IS_ASKM_40NM
775    case NEXUS_SecurityKeyType_eIv:
776        rv = BCMD_KeyDestEntryType_eIV;
777        break;
778#endif
779    default:
780        BERR_TRACE(NEXUS_INVALID_PARAMETER);
781    }
782    return rv;
783}
784
785#define NEXUS_SECURITY_CACP_INVALID_PIDCHANNEL 0xFFFFFFFF
786
787static NEXUS_Error NEXUS_Security_AllocateKeySlotForType(NEXUS_KeySlotHandle *pKeyHandle, NEXUS_SecurityEngine engine, BCMD_XptSecKeySlot_e type)
788{
789    BERR_Code rc;
790    NEXUS_KeySlotHandle pHandle;
791    unsigned int keyslotNumber;
792
793    pHandle = NEXUS_P_Core_AllocateKeySlotHandle();
794    if ( !pHandle) { return BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY); }
795
796    rc = BHSM_AllocateCAKeySlot(g_security.hsm, type, &keyslotNumber);
797    if (rc) goto error;
798
799    pHandle->keyslotType = type;
800    pHandle->pidChannel = NEXUS_SECURITY_CACP_INVALID_PIDCHANNEL;
801    pHandle->keySlotNumber = keyslotNumber;
802    pHandle->cryptoEngine = engine;
803
804    *pKeyHandle = pHandle;
805
806    BDBG_MSG(("%s: Allocated keyslot %p",__FUNCTION__,pHandle));
807
808    NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, true);
809
810    return NEXUS_SUCCESS;
811error:
812    NEXUS_P_Core_FreeKeySlotHandle(pHandle);
813    *pKeyHandle = NULL;
814    return BERR_TRACE(MAKE_HSM_ERR(rc));
815}
816
817NEXUS_KeySlotHandle NEXUS_Security_LocateCaKeySlotAssigned(unsigned long pidchannel)
818{
819    BERR_Code rc;
820    NEXUS_Security_P_KeySlotListNode *p;
821    unsigned int keyslotNumber;
822    unsigned int keyslotType;
823
824    NEXUS_SECURITY_DUMP_KEYSLOTS;
825
826    rc = BHSM_LocateCAKeySlotAssigned(g_security.hsm, pidchannel, BHSM_PidChannelType_ePrimary, &keyslotType, &keyslotNumber);
827    if (rc) {
828        rc = BERR_TRACE(MAKE_HSM_ERR(rc));
829        goto error;
830    }
831    for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
832        NEXUS_Security_P_PidChannelListNode *q;
833        for (q=BLST_S_FIRST(&p->pidchannels);q!=NULL;q=BLST_S_NEXT(q,next)) {
834            if (q->pidchannel == pidchannel) {
835                if (p->handle->keySlotNumber != keyslotNumber || p->handle->keyslotType != keyslotType) {
836                    BDBG_WRN(("%s: number/type difference, keyslot tracking may be out of sync with HSM",__FUNCTION__));
837                }
838                return p->handle;
839            }
840        }
841    }
842error:
843    BDBG_WRN(("%s: PID Channel %d is not yet associated with any key slot",__FUNCTION__,pidchannel));
844    return NULL;
845}
846
847NEXUS_Error NEXUS_Security_AllocateCaKeySlot(NEXUS_KeySlotHandle *pKeyHandle)
848{
849#if HSM_IS_ASKM_40NM
850    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle, NEXUS_SecurityEngine_eCa, BCMD_XptSecKeySlot_eType0);
851#else
852    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle, NEXUS_SecurityEngine_eCa, BCMD_XptSecKeySlot_eType1);
853#endif
854}
855
856NEXUS_Error NEXUS_Security_AllocateCaCpKeySlot(NEXUS_KeySlotHandle *pKeyHandle)
857{
858#if HSM_IS_ASKM_40NM
859    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle, NEXUS_SecurityEngine_eCaCp, BCMD_XptSecKeySlot_eType0);
860#else
861#if HAS_TYPE7_KEYSLOTS
862    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle,NEXUS_SecurityEngine_eCaCp, BCMD_XptSecKeySlot_eType7);
863#elif !HAS_TYPE5_KEYSLOTS
864    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle, NEXUS_SecurityEngine_eCaCp, BCMD_XptSecKeySlot_eType4);
865#else
866    return NEXUS_Security_AllocateKeySlotForType(pKeyHandle, NEXUS_SecurityEngine_eCaCp, BCMD_XptSecKeySlot_eType6);
867#endif
868#endif
869}
870
871NEXUS_Error NEXUS_Security_AddPidChannelToKeySlot(NEXUS_KeySlotHandle keyHandle, const unsigned int pidChannel)
872{
873    BHSM_ConfigPidKeyPointerTableIO_t configPidKeyPointerTableIO;
874    BERR_Code rc;
875    NEXUS_Security_P_KeySlotListNode *p;
876
877    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
878    BDBG_MSG(("%s: %p(%d,%d)",__FUNCTION__,keyHandle,keyHandle->keySlotNumber,keyHandle->keyslotType));
879
880    for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
881        NEXUS_Security_P_PidChannelListNode *q = NULL;
882        for (q=BLST_S_FIRST(&p->pidchannels);q!=NULL;q=BLST_S_NEXT(q,next)) {
883            if ((q->pidchannel == pidChannel) && (p->handle != keyHandle)) {
884                BDBG_MSG(("pidchannel %d already has keyslot %p associated, breaking association",pidChannel,p->handle));
885                NEXUS_Security_P_RemovePidchannel(p,q);
886                break;
887            }
888        }
889    }
890    p = NEXUS_Security_P_LocateNodeByKeyslot(keyHandle);
891
892    configPidKeyPointerTableIO.unPidChannel = pidChannel;
893    configPidKeyPointerTableIO.ucKeySlotType = keyHandle->keyslotType;
894    configPidKeyPointerTableIO.unKeySlotNum = keyHandle->keySlotNumber;
895    configPidKeyPointerTableIO.pidChannelType = BHSM_PidChannelType_ePrimary;
896#if HSM_IS_ASKM_40NM
897    configPidKeyPointerTableIO.spidProgType = BHSM_SPIDProg_ePIDPointerA;
898    configPidKeyPointerTableIO.bResetPIDToDefault = false;
899    configPidKeyPointerTableIO.unKeySlotBType = 0;
900#else
901    configPidKeyPointerTableIO.unKeySlotB = 0;
902#endif
903    configPidKeyPointerTableIO.unKeySlotNumberB = 0;
904    configPidKeyPointerTableIO.unKeyPointerSel = 0;
905
906    rc = BHSM_ConfigPidKeyPointerTable(g_security.hsm, &configPidKeyPointerTableIO);
907    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
908
909    if (p) {
910        NEXUS_Security_P_PidChannelListNode *q = NULL;
911        bool has_pidchannel = false;
912        for (q=BLST_S_FIRST(&p->pidchannels);q!=NULL;q=BLST_S_NEXT(q,next)) {
913            if (q->pidchannel == pidChannel) {
914                has_pidchannel = true;
915            }
916        }
917        if (!has_pidchannel) {
918            NEXUS_Security_P_PidChannelListNode *node;
919            node = BKNI_Malloc(sizeof(*node));
920            if (node) {
921                BKNI_Memset(node,0,sizeof(*node));
922                node->pidchannel = pidChannel;
923                BLST_S_INSERT_HEAD(&p->pidchannels, node, next);
924            }
925        }
926    }
927    /* deprecated */
928    keyHandle->pidChannel = pidChannel;
929
930    NEXUS_SECURITY_DUMP_KEYSLOTS;
931
932    return NEXUS_SUCCESS;
933}
934
935NEXUS_Error NEXUS_Security_RemovePidChannelFromKeySlot(NEXUS_KeySlotHandle keyHandle, const unsigned int pidChannel)
936{
937    BHSM_ConfigPidKeyPointerTableIO_t configPidKeyPointerTableIO;
938    BERR_Code rc;
939    NEXUS_Security_P_KeySlotListNode *p;
940
941    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
942    BDBG_MSG(("%s: %p(%d,%d,%d)",__FUNCTION__,keyHandle,keyHandle->keySlotNumber,keyHandle->keyslotType,pidChannel));
943
944    p = NEXUS_Security_P_LocateNodeByKeyslot(keyHandle);
945    if (p) {
946        NEXUS_Security_P_PidChannelListNode *q;
947        for (q=BLST_S_FIRST(&p->pidchannels);q!=NULL;q=BLST_S_NEXT(q,next)) {
948            if (q->pidchannel == pidChannel) {
949                NEXUS_Security_P_RemovePidchannel(p,q);
950                configPidKeyPointerTableIO.unPidChannel = pidChannel;
951                configPidKeyPointerTableIO.ucKeySlotType = keyHandle->keyslotType;
952                configPidKeyPointerTableIO.unKeySlotNum = keyHandle->keySlotNumber;
953                configPidKeyPointerTableIO.pidChannelType = BHSM_PidChannelType_ePrimary;
954#if HSM_IS_ASKM_40NM
955                configPidKeyPointerTableIO.spidProgType = BHSM_SPIDProg_ePIDPointerA;
956                configPidKeyPointerTableIO.bResetPIDToDefault = false;
957                configPidKeyPointerTableIO.unKeySlotBType = 0;
958#else
959                configPidKeyPointerTableIO.unKeySlotB = 0;
960#endif
961                configPidKeyPointerTableIO.unKeySlotNumberB = 0;
962                configPidKeyPointerTableIO.unKeyPointerSel = 0;
963
964                rc = BHSM_ConfigPidChannelToDefaultKeySlot(g_security.hsm, &configPidKeyPointerTableIO);
965                if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
966                p->handle->pidChannel = NEXUS_SECURITY_CACP_INVALID_PIDCHANNEL; /* deprecated */
967                break;
968            }
969        }
970    }
971
972    NEXUS_SECURITY_DUMP_KEYSLOTS;
973
974    return NEXUS_SUCCESS;
975}
976
977void NEXUS_Security_GetDefaultInvalidateKeySettings(NEXUS_SecurityInvalidateKeySettings *pSettings /* [out] */ )
978{
979    if (pSettings) {
980        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
981    }
982}
983
984static NEXUS_Error NEXUS_Security_P_InvalidateKey(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityInvalidateKeySettings *pSettings)
985{
986    BHSM_InvalidateKeyIO_t invalidateKeyIO;
987    BERR_Code rc;
988
989    BDBG_MSG(("NEXUS_Security_P_InvalidateKey: %p(%d,%d)",keyHandle,keyHandle->keySlotNumber,keyHandle->keyslotType));
990
991    invalidateKeyIO.invalidKeyType = (BCMD_InvalidateKey_Flag_e)pSettings->invalidateKeyType;
992    invalidateKeyIO.keyDestBlckType = (BCMD_KeyDestBlockType_e)pSettings->keyDestBlckType;
993    invalidateKeyIO.keyDestEntryType = NEXUS_Security_MapNexusKeyDestToHsm(keyHandle, pSettings->keyDestEntryType);
994    invalidateKeyIO.caKeySlotType = (BCMD_XptSecKeySlot_e)keyHandle->keyslotType;
995    invalidateKeyIO.unKeySlotNum = keyHandle->keySlotNumber;
996#if HSM_IS_ASKM
997    invalidateKeyIO.virtualKeyLadderID = (BCMD_VKLID_e)pSettings->virtualKeyLadderID;
998    invalidateKeyIO.keyLayer = (BCMD_KeyRamBuf_e)pSettings->keySrc;
999#else
1000    invalidateKeyIO.keySrc = (BCMD_KeyRamBuf_e)pSettings->keySrc;
1001#endif
1002
1003    rc = BHSM_InvalidateKey(g_security.hsm, &invalidateKeyIO);
1004    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
1005
1006    return NEXUS_SUCCESS;
1007
1008}
1009
1010
1011NEXUS_Error NEXUS_Security_InvalidateKey(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityInvalidateKeySettings *pSettings)
1012{
1013    BERR_Code rc;
1014
1015    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
1016    BDBG_MSG(("NEXUS_Security_InvalidateKey: %p(%d,%d)",keyHandle,keyHandle->keySlotNumber,keyHandle->keyslotType));
1017
1018    if (pSettings->keyDestEntryType == NEXUS_SecurityKeyType_eOddAndEven) {
1019        /* Special case: NEXUS_SecurityKeyType_eOddAndEven means all CA keys
1020         * Since pSettings is const, we make a local copy and iterate through the possible destinations.
1021         */
1022        NEXUS_SecurityInvalidateKeySettings keySettings;
1023        BKNI_Memcpy(&keySettings, pSettings, sizeof(keySettings));
1024        keySettings.keyDestEntryType = NEXUS_SecurityKeyType_eOdd;
1025        rc = NEXUS_Security_P_InvalidateKey(keyHandle, &keySettings);
1026        if (!rc) {
1027            keySettings.keyDestEntryType = NEXUS_SecurityKeyType_eEven;
1028            rc = NEXUS_Security_P_InvalidateKey(keyHandle, &keySettings);
1029        }
1030        if (!rc && ((keyHandle->cryptoEngine == NEXUS_SecurityEngine_eRmx) || (keyHandle->cryptoEngine == NEXUS_SecurityEngine_eCaCp))) {
1031            keySettings.keyDestEntryType = NEXUS_SecurityKeyType_eClear;
1032            rc = NEXUS_Security_P_InvalidateKey(keyHandle, &keySettings);
1033        }
1034    } else {
1035        rc = NEXUS_Security_P_InvalidateKey(keyHandle, pSettings);
1036    }
1037    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
1038    return NEXUS_SUCCESS;
1039}
1040
1041static BCMD_XptSecKeySlot_e NEXUS_Security_MapNexusKeySlotTypeToHsm(NEXUS_SecurityKeySlotType slotType, NEXUS_SecurityEngine engine)
1042{
1043    BCMD_XptSecKeySlot_e rvType = BCMD_XptSecKeySlot_eType0;
1044    if (slotType != NEXUS_SecurityKeySlotType_eAuto) {
1045        /* We were given a specific HSM keyslot type, therefore perform a straight mapping */
1046        switch(slotType) {
1047            /* The _eTypeX values map directly to the equivalent HSM variable
1048             * Macro trickery to avoid copy/paste errors */
1049#define NEXUS_REMAP_HSM_ETYPE(VAL) \
1050            case NEXUS_SecurityKeySlotType_eType##VAL : \
1051                rvType = BCMD_XptSecKeySlot_eType##VAL ; \
1052                break;
1053            NEXUS_REMAP_HSM_ETYPE(0)
1054            NEXUS_REMAP_HSM_ETYPE(1)
1055            NEXUS_REMAP_HSM_ETYPE(2)
1056            NEXUS_REMAP_HSM_ETYPE(3)
1057            NEXUS_REMAP_HSM_ETYPE(4)
1058#if HAS_TYPE5_KEYSLOTS
1059            NEXUS_REMAP_HSM_ETYPE(5)
1060            NEXUS_REMAP_HSM_ETYPE(6)
1061#endif
1062#if HAS_TYPE7_KEYSLOTS
1063            NEXUS_REMAP_HSM_ETYPE(7)
1064#endif
1065#undef NEXUS_REMAP_HSM_ETYPE
1066        case NEXUS_SecurityKeySlotType_eAuto:
1067        default:
1068            BERR_TRACE(NEXUS_INVALID_PARAMETER);
1069            BDBG_ASSERT(0);
1070        }
1071    } else {
1072        /* Determine the keyslot type based on... */
1073        switch (engine) {
1074        case NEXUS_SecurityEngine_eM2m:
1075#if HSM_IS_ASKM_40NM
1076            rvType = BCMD_XptSecKeySlot_eType0;
1077#else
1078            rvType = BCMD_XptSecKeySlot_eType1;
1079#endif
1080            break;
1081        case NEXUS_SecurityEngine_eCa:
1082#if HSM_IS_ASKM_40NM
1083            rvType = BCMD_XptSecKeySlot_eType0;
1084#else
1085            rvType = BCMD_XptSecKeySlot_eType1;
1086#endif
1087            break;
1088        case NEXUS_SecurityEngine_eCaCp:
1089        case NEXUS_SecurityEngine_eRmx:
1090#if HSM_IS_ASKM_40NM
1091            rvType = BCMD_XptSecKeySlot_eType0;
1092#else
1093#if HAS_TYPE7_KEYSLOTS
1094            rvType = BCMD_XptSecKeySlot_eType7;
1095#elif !HAS_TYPE5_KEYSLOTS
1096            rvType = BCMD_XptSecKeySlot_eType4;
1097#else
1098            rvType = BCMD_XptSecKeySlot_eType6;
1099#endif
1100#endif
1101            break;
1102        case NEXUS_SecurityEngine_eCp:
1103        default:
1104            /* an unsupported or invalid security engine value was passed in. */
1105            BERR_TRACE(NEXUS_INVALID_PARAMETER);
1106            BDBG_ASSERT(0);
1107        }
1108    }
1109    return rvType;
1110}
1111
1112NEXUS_Error NEXUS_Security_AllocateM2mKeySlot(NEXUS_KeySlotHandle * pKeyHandle)
1113{
1114    BERR_Code rc;
1115    NEXUS_KeySlotHandle pHandle;
1116    unsigned int keyslotNumber;
1117
1118    BDBG_MSG(("Allocating M2M keyslot"));
1119
1120    BDBG_ASSERT(pKeyHandle);
1121    pHandle = NEXUS_P_Core_AllocateKeySlotHandle();
1122    if ( !pHandle) { *pKeyHandle = NULL; return BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY); }
1123
1124    rc = BHSM_AllocateM2MKeySlot(g_security.hsm, &keyslotNumber);
1125    if (rc) {
1126        NEXUS_P_Core_FreeKeySlotHandle(pHandle);
1127        *pKeyHandle = NULL;
1128        BDBG_MSG(("Failed to allocate M2M keyslot (rc = %x)", rc));
1129        return BERR_TRACE(MAKE_HSM_ERR(rc));
1130    }
1131
1132    pHandle->keyslotType = NEXUS_Security_MapNexusKeySlotTypeToHsm(pHandle->keyslotType,NEXUS_SecurityEngine_eM2m);
1133    pHandle->keySlotNumber = keyslotNumber;
1134    pHandle->cryptoEngine = NEXUS_SecurityEngine_eM2m;
1135    BDBG_MSG(("Allocated M2M keyslot %d", keyslotNumber));
1136
1137    *pKeyHandle = pHandle;
1138
1139    NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, true);
1140    return NEXUS_SUCCESS;
1141}
1142
1143#if HSM_IS_ASKM
1144
1145void NEXUS_Security_GetDefaultAlgorithmSettings(
1146        NEXUS_SecurityAlgorithmSettings * pSettings
1147)
1148{
1149
1150    if (pSettings)
1151    {
1152        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
1153        pSettings->algorithm = NEXUS_SecurityAlgorithm_e3DesAba;
1154        pSettings->algorithmVar = NEXUS_SecurityAlgorithmVariant_eEcb;
1155        pSettings->terminationMode = NEXUS_SecurityTerminationMode_eClear;
1156        pSettings->aesCounterSize = NEXUS_SecurityAesCounterSize_e32Bits;
1157        pSettings->dvbScramLevel = NEXUS_SecurityDvbScrambleLevel_eTs;
1158        pSettings->operation = NEXUS_SecurityOperation_ePassThrough;
1159        pSettings->keyDestEntryType = NEXUS_SecurityKeyType_eOddAndEven;
1160        pSettings->testKey2Select = false;
1161        pSettings->bRestrictEnable = true;
1162        pSettings->bGlobalEnable = true;
1163        pSettings->bScAtscMode = false;
1164        pSettings->bAtscModEnable = false;
1165        pSettings->bGlobalDropPktEnable = false;
1166        pSettings->bRestrictDropPktEnable = false;
1167        pSettings->bGlobalRegionOverwrite = false;
1168        pSettings->bEncryptBeforeRave = false;
1169        pSettings->enableExtIv = false;
1170        pSettings->enableExtKey = false;
1171        pSettings->mscBitSelect = false;
1172        pSettings->bDisallowGG = false;
1173        pSettings->bDisallowGR = false;
1174        pSettings->bDisallowRG = false;
1175        pSettings->bDisallowRR = false;
1176
1177        /* ASKM default virtual keyladder configuration -- this is suitable for apps which are not using
1178         * these features and are built for a generic part.  It is expected that the app will override
1179         * these values if actually using ASKM features.
1180         *
1181         * Added to NEXUS_Security_GetDefaultAlgorithmSettings to allow older apps to work on
1182         * newer parts without modification.
1183         */
1184        pSettings->ivMode = NEXUS_SecurityIVMode_eRegular;
1185        pSettings->solitarySelect = NEXUS_SecuritySolitarySelect_eClear;
1186        pSettings->caVendorID = 0x1234;
1187        pSettings->askmModuleID = NEXUS_SecurityAskmModuleID_eModuleID_4;
1188        pSettings->otpId = NEXUS_SecurityOtpId_eOtpVal;
1189        pSettings->testKey2Select = 0;
1190
1191    }
1192}
1193
1194static BCMD_XptM2MSecCryptoAlg_e NEXUS_Security_MapNexusAlgorithmToHsm(NEXUS_SecurityAlgorithm algorithm)
1195{
1196    BCMD_XptM2MSecCryptoAlg_e rvAlgorithm = algorithm;
1197
1198    switch (algorithm)
1199    {
1200    case NEXUS_SecurityAlgorithm_eMulti2:
1201        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eMulti2;
1202        break;
1203    case NEXUS_SecurityAlgorithm_eDes:
1204        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eDes;
1205        break;
1206    case NEXUS_SecurityAlgorithm_e3DesAba:
1207        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_e3DesAba;
1208        break;
1209    case NEXUS_SecurityAlgorithm_e3DesAbc:
1210        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_e3DesAbc;
1211        break;
1212    case NEXUS_SecurityAlgorithm_eAes:
1213        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eAes128;
1214        break;
1215    case NEXUS_SecurityAlgorithm_eAes192:
1216        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eAes192;
1217        break;
1218    case NEXUS_SecurityAlgorithm_eC2:
1219        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eC2;
1220        break;
1221    case NEXUS_SecurityAlgorithm_eCss:
1222        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eCss;
1223        break;
1224    case NEXUS_SecurityAlgorithm_eM6Ke:
1225        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eM6KE;
1226        break;
1227    case NEXUS_SecurityAlgorithm_eM6:
1228        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eM6;
1229        break;
1230    case NEXUS_SecurityAlgorithm_eWMDrmPd:
1231        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eWMDrmPd;
1232        break;
1233       
1234#if HSM_IS_ASKM_40NM
1235    case NEXUS_SecurityAlgorithm_eDvbCsa3:
1236        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eDVBCSA3;
1237        break;
1238    case NEXUS_SecurityAlgorithm_eAsf:
1239#if HSM_IS_ASKM_40NM_ZEUS_2_5
1240        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eAesCounter0;
1241#else
1242        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eASF;
1243#endif
1244        break;
1245    case NEXUS_SecurityAlgorithm_eMSMultiSwapMac:
1246        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eMSMULTISWAPMAC;
1247        break;
1248#if HSM_IS_ASKM_40NM_ZEUS_2_0
1249    case NEXUS_SecurityAlgorithm_eAsa:
1250        rvAlgorithm = BCMD_XptM2MSecCryptoAlg_eASA;
1251        break;
1252#endif
1253#endif
1254    /* The _eReservedX values should pass the literal value X into HSM,
1255     * allowing direct control of custom modes
1256     * Macro trickery to avoid copy/paste errors */
1257#define NEXUS_REMAP_RESERVED(VAL) \
1258    case NEXUS_SecurityAlgorithm_eReserved##VAL : \
1259        rvAlgorithm = (BCMD_XptM2MSecCryptoAlg_e) VAL ; \
1260        break;
1261        NEXUS_REMAP_RESERVED(0)
1262        NEXUS_REMAP_RESERVED(1)
1263        NEXUS_REMAP_RESERVED(2)
1264        NEXUS_REMAP_RESERVED(3)
1265        NEXUS_REMAP_RESERVED(4)
1266        NEXUS_REMAP_RESERVED(5)
1267        NEXUS_REMAP_RESERVED(6)
1268        NEXUS_REMAP_RESERVED(7)
1269        NEXUS_REMAP_RESERVED(8)
1270#undef NEXUS_REMAP_RESERVED
1271    default:
1272        break;
1273    }
1274
1275    return rvAlgorithm;
1276}
1277
1278static void NEXUS_Security_GetHsmAlgorithmKeySetting(
1279        NEXUS_KeySlotHandle keyHandle,
1280        const NEXUS_SecurityAlgorithmSettings *pSettings,
1281        BCMD_XptM2MSecCryptoAlg_e *pCryptAlg,
1282        BCMD_CipherModeSelect_e *pCipherMode,
1283        BCMD_TerminationMode_e *pTerminationMode
1284)
1285{
1286
1287    /* fixups/remapping needed since the enums do not always agree across all platforms */
1288    *pCryptAlg = NEXUS_Security_MapNexusAlgorithmToHsm(pSettings->algorithm);
1289    *pCipherMode = (BCMD_CipherModeSelect_e)pSettings->algorithmVar;
1290    *pTerminationMode = (BCMD_TerminationMode_e)pSettings->terminationMode;
1291
1292    if ( keyHandle->cryptoEngine != NEXUS_SecurityEngine_eM2m )
1293    {
1294        if (pSettings->algorithm == NEXUS_SecurityAlgorithm_eDvb ||
1295            pSettings->algorithm == NEXUS_SecurityAlgorithm_eDvbCsa3)
1296        {
1297            /* overload cipherMode for CA/CP */
1298            if (pSettings->dvbScramLevel == NEXUS_SecurityDvbScrambleLevel_eTs)
1299                *pCipherMode = (BCMD_CipherModeSelect_e)NEXUS_SecurityAlgorithmVariant_eXpt;
1300            else
1301                *pCipherMode = (BCMD_CipherModeSelect_e)NEXUS_SecurityAlgorithmVariant_ePes;
1302
1303        }
1304
1305    }
1306    else /* Security Algorithm Key setting for M2M */
1307    {
1308        if (pSettings->algorithm == NEXUS_SecurityAlgorithm_eAes ||
1309                pSettings->algorithm == NEXUS_SecurityAlgorithm_eAes192)
1310        {
1311            if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eCounter)
1312            {
1313                /* overload termination mode for M2M */
1314                *pTerminationMode = pSettings->aesCounterSize;
1315            }
1316        }
1317    }
1318
1319}
1320
1321#else
1322
1323void NEXUS_Security_GetDefaultAlgorithmSettings(NEXUS_SecurityAlgorithmSettings * pSettings)
1324{
1325    if (pSettings) {
1326        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
1327        pSettings->algorithm = NEXUS_SecurityAlgorithm_e3DesAba;
1328        pSettings->algorithmVar = NEXUS_SecurityAlgorithmVariant_eEcb;
1329        pSettings->terminationMode = NEXUS_SecurityTerminationMode_eCipherStealing;
1330        pSettings->aesCounterSize = NEXUS_SecurityAesCounterSize_e32Bits;
1331        pSettings->dvbScramLevel = NEXUS_SecurityDvbScrambleLevel_eTs;
1332        pSettings->keyDestEntryType = NEXUS_SecurityKeyType_eOddAndEven;
1333        pSettings->operation = NEXUS_SecurityOperation_ePassThrough;
1334        pSettings->bRestrictEnable = true;
1335        pSettings->bGlobalEnable = true;
1336        pSettings->bScAtscMode = false;
1337        pSettings->bAtscModEnable = false;
1338        pSettings->bGlobalDropPktEnable = false;
1339        pSettings->bRestrictDropPktEnable = false;
1340        pSettings->bGlobalRegionOverwrite = false;
1341        pSettings->enableExtIv = false;
1342        pSettings->enableExtKey = false;
1343        pSettings->mscBitSelect = false;
1344        pSettings->bScPolarityEnable = false;
1345        pSettings->bSynEnable = false;
1346        pSettings->bCPDDisable = false;
1347        pSettings->bCPSDisable = false;
1348    }
1349}
1350
1351static bool NEXUS_Security_GetHsmCaCpRmxAlgorithmKeySetting(const NEXUS_SecurityAlgorithmSettings * pSettings, unsigned int * pCryptAlg, BHSM_ResidueMode_e * pResidualMode)
1352{
1353    switch (pSettings->algorithm) {
1354    case NEXUS_SecurityAlgorithm_eDvb: {
1355        *pCryptAlg = BCMD_XptSecCryptoAlg_eDvb;
1356        if (pSettings->dvbScramLevel == NEXUS_SecurityDvbScrambleLevel_eTs)
1357            *pResidualMode = BHSM_DVBScrambleLevel_eTS;
1358        else
1359            *pResidualMode = BHSM_DVBScrambleLevel_ePes;
1360    }
1361        return true;
1362
1363    case NEXUS_SecurityAlgorithm_eDes: {
1364        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1365            *pCryptAlg = BCMD_XptSecCryptoAlg_eDesEcb;
1366        else
1367            *pCryptAlg = BCMD_XptSecCryptoAlg_eDesCbc;
1368    }
1369        break;
1370    case NEXUS_SecurityAlgorithm_e3DesAba: {
1371        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1372            *pCryptAlg = BCMD_XptSecCryptoAlg_e3DesAbaEcb;
1373        else
1374            *pCryptAlg = BCMD_XptSecCryptoAlg_e3DesAbaCbc;
1375    }
1376        break;
1377#if SUPPORT_NON_DTV_CRYPTO || SUPPORT_AES_FOR_DTV
1378    case NEXUS_SecurityAlgorithm_eAes: {
1379        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1380            *pCryptAlg = BCMD_XptSecCryptoAlg_eAesEcb;
1381        else
1382            *pCryptAlg = BCMD_XptSecCryptoAlg_eAesCbc;
1383    }
1384        break;
1385#endif /* SUPPORT_NON_DTV_CRYPTO */
1386    case NEXUS_SecurityAlgorithm_eMulti2: {
1387        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1388            *pCryptAlg = BCMD_XptSecCryptoAlg_eMulti2Ecb;
1389        else
1390            *pCryptAlg = BCMD_XptSecCryptoAlg_eMulti2Cbc;
1391        break;
1392    }
1393    default:
1394#if SUPPORT_NON_DTV_CRYPTO
1395        *pCryptAlg = BCMD_XptSecCryptoAlg_eAesEcb;
1396#else
1397        * pCryptAlg = BCMD_XptSecCryptoAlg_eDesEcb;
1398#endif /* SUPPORT_NON_DTV_CRYPTO */
1399        BDBG_WRN(("Unrecognized or unsupported algorithm"));
1400        BERR_TRACE(BERR_INVALID_PARAMETER);
1401        break;
1402    }
1403
1404    return false;
1405}
1406
1407static bool NEXUS_Security_GetHsmM2MAlgorithmKeySetting(const NEXUS_SecurityAlgorithmSettings *pSettings, unsigned int * pCryptAlg, BHSM_ResidueMode_e * pResidualMode)
1408{
1409    switch (pSettings->algorithm) {
1410    case NEXUS_SecurityAlgorithm_e3DesAba: {
1411        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1412            *pCryptAlg = BCMD_M2MSecCryptoAlg_e3DesAbaEcb;
1413        else
1414            *pCryptAlg = BCMD_M2MSecCryptoAlg_e3DesAbaCbc;
1415    }
1416        break;
1417    case NEXUS_SecurityAlgorithm_e3DesAbc: {
1418        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1419            *pCryptAlg = BCMD_M2MSecCryptoAlg_e3DesAbcEcb;
1420        else
1421            *pCryptAlg = BCMD_M2MSecCryptoAlg_e3DesAbcCbc;
1422    }
1423        break;
1424    case NEXUS_SecurityAlgorithm_eDes: {
1425        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1426            *pCryptAlg = BCMD_M2MSecCryptoAlg_eDesEcb;
1427        else
1428            *pCryptAlg = BCMD_M2MSecCryptoAlg_eDesCbc;
1429    }
1430        break;
1431#if SUPPORT_NON_DTV_CRYPTO
1432    case NEXUS_SecurityAlgorithm_eC2: {
1433        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1434            *pCryptAlg = BCMD_M2MSecCryptoAlg_eC2Ecb;
1435        else
1436            *pCryptAlg = BCMD_M2MSecCryptoAlg_eC2Cbc;
1437    }
1438        break;
1439#endif /* SUPPORT_NON_DTV_CRYPTO */
1440#if SUPPORT_NON_DTV_CRYPTO
1441    case NEXUS_SecurityAlgorithm_eCss:
1442        *pCryptAlg = BCMD_M2MSecCryptoAlg_eCss;
1443        break;
1444#endif /* SUPPORT_NON_DTV_CRYPTO */
1445    case NEXUS_SecurityAlgorithm_eM6Ke:
1446        *pCryptAlg = BCMD_M2MSecCryptoAlg_eM6KE;
1447        break;
1448    case NEXUS_SecurityAlgorithm_eM6: {
1449        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1450            *pCryptAlg = BCMD_M2MSecCryptoAlg_eM6Ecb;
1451        else
1452            *pCryptAlg = BCMD_M2MSecCryptoAlg_eM6Cbc;
1453    }
1454        break;
1455    case NEXUS_SecurityAlgorithm_eAes: {
1456        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1457            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes128Ecb;
1458        else if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eCbc)
1459            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes128Cbc;
1460        else
1461            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAesCounter;
1462    }
1463        break;
1464    case NEXUS_SecurityAlgorithm_eAes192: {
1465        if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eEcb)
1466            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes192Ecb;
1467        else if (pSettings->algorithmVar == NEXUS_SecurityAlgorithmVariant_eCbc)
1468            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes192Cbc;
1469        else
1470            *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes192Counter;
1471    }
1472        break;
1473#if MSDRM_PD_SUPPORT
1474        case NEXUS_SecurityAlgorithm_eWMDrmPd:
1475        * pCryptAlg = BCMD_M2MSecCryptoAlg_eWMDrmPd;
1476        break;
1477        case NEXUS_SecurityAlgorithm_eRc4:
1478        * pCryptAlg = BCMD_M2MSecCryptoAlg_eRc4;
1479        break;
1480#endif
1481    default:
1482        *pCryptAlg = BCMD_M2MSecCryptoAlg_eAes128Ecb;
1483        break;
1484    }
1485
1486    if ( (*pCryptAlg == BCMD_M2MSecCryptoAlg_eAesCounter) || (*pCryptAlg == BCMD_M2MSecCryptoAlg_eAes192Counter)) {
1487        *pResidualMode = pSettings->aesCounterSize;
1488        return true;
1489    }
1490    return false;
1491}
1492
1493static void NEXUS_Security_GetHsmAlgorithmKeySetting(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityAlgorithmSettings *pSettings, unsigned int * pCryptAlg,
1494        BHSM_ResidueMode_e * pResidualMode)
1495{
1496    if (keyHandle->cryptoEngine != NEXUS_SecurityEngine_eM2m) {
1497        if (NEXUS_Security_GetHsmCaCpRmxAlgorithmKeySetting(pSettings, pCryptAlg, pResidualMode))
1498            return;
1499    } else {
1500        if (NEXUS_Security_GetHsmM2MAlgorithmKeySetting(pSettings, pCryptAlg, pResidualMode))
1501            return;
1502    }
1503
1504    switch (pSettings->terminationMode) {
1505    case NEXUS_SecurityTerminationMode_eClear:
1506        *pResidualMode = BHSM_ResidueMode_eUnscrambled;
1507        break;
1508    case NEXUS_SecurityTerminationMode_eBlock:
1509        *pResidualMode = BHSM_ResidueMode_eResidueBlock;
1510        break;
1511    case NEXUS_SecurityTerminationMode_eCipherStealing:
1512        *pResidualMode = BHSM_ResidueMode_eCipherTextStealing;
1513        break;
1514#if 0 /*RRLee BHSM_ResidueMode_eCipherStealingComcast is not defined???*/
1515        case NEXUS_SecurityTerminationMode_eCipherStealingComcast:
1516        * pResidualMode = BHSM_ResidueMode_eCipherStealingComcast;
1517        break;
1518#endif
1519    default:
1520        *pResidualMode = BHSM_ResidueMode_eUnscrambled;
1521        break;
1522    }
1523
1524}
1525
1526#endif
1527static NEXUS_Error NEXUS_Security_GetHsmDestBlkType(NEXUS_Security_P_KeySlotListNode *p, NEXUS_SecurityAlgorithmConfigDestination dest, BCMD_KeyDestBlockType_e *pType)
1528{
1529    switch (p->handle->cryptoEngine) {
1530    case NEXUS_SecurityEngine_eCa:
1531        *pType = BCMD_KeyDestBlockType_eCA;
1532        break;
1533    case NEXUS_SecurityEngine_eM2m:
1534        *pType = BCMD_KeyDestBlockType_eMem2Mem;
1535        break;
1536    case NEXUS_SecurityEngine_eCaCp:
1537#if HSM_IS_ASKM
1538        if (dest == NEXUS_SecurityAlgorithmConfigDestination_eCa)
1539            *pType = BCMD_KeyDestBlockType_eCA;
1540        else if (dest == NEXUS_SecurityAlgorithmConfigDestination_eCpd)
1541            *pType = BCMD_KeyDestBlockType_eCPDescrambler;
1542        else if (dest == NEXUS_SecurityAlgorithmConfigDestination_eCps)
1543            *pType = BCMD_KeyDestBlockType_eCPScrambler;
1544#else
1545#if 0
1546        /* If configuring an AES128 key for CPS is erroring, try this code instead: */
1547        if (p->algorithm == NEXUS_SecurityAlgorithm_eAes128) {
1548            /* AES128 requires CPS for scrambling on older chips */
1549            *pType = (dest==NEXUS_SecurityAlgorithmConfigDestination_eCa) ? BCMD_KeyDestBlockType_eCA : BCMD_KeyDestBlockType_eCPScrambler;
1550        } else {
1551            /* Everything else uses Remux on older chips */
1552            *pType = (dest==NEXUS_SecurityAlgorithmConfigDestination_eCa) ? BCMD_KeyDestBlockType_eCA : BCMD_KeyDestBlockType_eRmx;
1553        }
1554#else
1555        *pType = (dest==NEXUS_SecurityAlgorithmConfigDestination_eCa) ? BCMD_KeyDestBlockType_eCA : BCMD_KeyDestBlockType_eRmx;
1556#endif
1557#endif
1558        break;
1559    case NEXUS_SecurityEngine_eCp:
1560#if HSM_IS_ASKM
1561        if (dest == NEXUS_SecurityAlgorithmConfigDestination_eCpd)
1562            *pType = BCMD_KeyDestBlockType_eCPDescrambler;
1563        else if (dest == NEXUS_SecurityAlgorithmConfigDestination_eCps)
1564            *pType = BCMD_KeyDestBlockType_eCPScrambler;
1565
1566#else
1567#if 0
1568        if (p->algorithm == NEXUS_SecurityAlgorithm_eAes128) {
1569            /* AES128 requires CPS for scrambling on older chips */
1570            *pType = BCMD_KeyDestBlockType_eCPScrambler;
1571        } else {
1572            /* Everything else uses Remux on older chips */
1573            *pType = BCMD_KeyDestBlockType_eRmx;
1574        }
1575#else
1576        *pType = BCMD_KeyDestBlockType_eRmx;
1577#endif
1578#endif
1579        break;
1580    case NEXUS_SecurityEngine_eRmx:
1581#if HSM_IS_ASKM_40NM
1582        BDBG_ERR(("Remux is not supported on 40nm HSM"));
1583        *pType = BCMD_KeyDestBlockType_eCA;
1584        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1585#else
1586        *pType = BCMD_KeyDestBlockType_eRmx;
1587#endif
1588        break;
1589    default:
1590        /* There is no meaningful default, error. */
1591        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1592        break;
1593    }
1594    return NEXUS_SUCCESS;
1595}
1596
1597static NEXUS_Error NEXUS_Security_GetHsmDestEntrykType(NEXUS_SecurityKeyType keytype, BCMD_KeyDestEntryType_e *pType)
1598{
1599    switch (keytype) {
1600    case NEXUS_SecurityKeyType_eEven:
1601        *pType = BCMD_KeyDestEntryType_eEvenKey;
1602        break;
1603    case NEXUS_SecurityKeyType_eOdd:
1604        *pType = BCMD_KeyDestEntryType_eOddKey;
1605        break;
1606    case NEXUS_SecurityKeyType_eClear:
1607#if HSM_IS_ASKM_40NM
1608        *pType = BCMD_KeyDestEntryType_eReserved2;
1609#else
1610        *pType = BCMD_KeyDestEntryType_eReserved0;
1611#endif
1612        break;
1613#if !HSM_IS_ASKM_40NM
1614    case NEXUS_SecurityKeyType_eIv:
1615        *pType = BCMD_KeyDestEntryType_eIV;
1616        break;
1617#endif
1618    default:
1619        *pType = BCMD_KeyDestEntryType_eOddKey;
1620        break;
1621    }
1622    return NEXUS_SUCCESS;
1623}
1624
1625#if HSM_IS_ASKM_40NM
1626static NEXUS_Error NEXUS_Security_GetHsmDestIVType(NEXUS_SecurityKeyIVType keyIVtype, BCMD_KeyDestIVType_e *pType)
1627{
1628    switch (keyIVtype) {
1629    case NEXUS_SecurityKeyIVType_eNoIV:
1630        *pType = BCMD_KeyDestIVType_eNoIV;
1631        break;
1632    case NEXUS_SecurityKeyIVType_eIV:
1633        *pType = BCMD_KeyDestIVType_eIV;
1634        break;
1635    case NEXUS_SecurityKeyIVType_eAesShortIV:
1636        *pType = BCMD_KeyDestIVType_eAesShortIV;
1637        break;
1638    default:
1639        *pType = BCMD_KeyDestIVType_eNoIV;
1640        break;
1641    }
1642    return NEXUS_SUCCESS;
1643}
1644
1645#endif
1646#ifdef NEXUS_SECURITY_SC_VALUE
1647static int g_scValues[NEXUS_SecurityAlgorithmScPolarity_eMax] = { 0, 1, 2, 3 };
1648#endif
1649static void NEXUS_Security_P_SetScValues(BHSM_ConfigAlgorithmIO_t *pConfigAlgorithmIO, const NEXUS_SecurityAlgorithmSettings *pSettings, NEXUS_SecurityKeyType keyType) {
1650#if HSM_IS_ASKM_40NM && defined(NEXUS_SECURITY_SC_VALUE)
1651    int keytypeScValues[NEXUS_SecurityKeyType_eMax] = { 3, 2, 0, 0, 0 };
1652    if (pSettings->modifyScValue[NEXUS_SecurityPacketType_eGlobal]) {
1653        pConfigAlgorithmIO->cryptoAlg.caCryptAlg.globalSCVal = g_scValues[pSettings->scValue[NEXUS_SecurityPacketType_eGlobal]];
1654    } else {
1655        pConfigAlgorithmIO->cryptoAlg.caCryptAlg.globalSCVal = keytypeScValues[keyType];
1656    }
1657    if (pSettings->modifyScValue[NEXUS_SecurityPacketType_eRestricted]) {
1658        pConfigAlgorithmIO->cryptoAlg.caCryptAlg.restrSCVal = g_scValues[pSettings->scValue[NEXUS_SecurityPacketType_eRestricted]];
1659    } else {
1660        pConfigAlgorithmIO->cryptoAlg.caCryptAlg.restrSCVal = keytypeScValues[keyType];
1661    }
1662#else
1663    BSTD_UNUSED(pConfigAlgorithmIO);
1664    BSTD_UNUSED(pSettings);
1665    BSTD_UNUSED(keyType);
1666#endif
1667}
1668
1669NEXUS_Error NEXUS_Security_ConfigAlgorithm(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityAlgorithmSettings *pSettings)
1670{
1671    BHSM_ConfigAlgorithmIO_t configAlgorithmIO;
1672    BCMD_XptSecKeySlot_e keySlotType;
1673    unsigned int unKeySlotNum = 0;
1674    bool bConfigOddAndEven = false;
1675#if !HSM_IS_ASKM_40NM
1676    bool bConfigClear = false;
1677#endif
1678    NEXUS_Error rc = NEXUS_SUCCESS;
1679    BCMD_KeyDestBlockType_e blockType = BCMD_KeyDestBlockType_eCA;
1680#if HSM_IS_ASKM
1681    BHSM_ConfigKeySlotIDDataIO_t configKeySlotIDDataIO;
1682    BCMD_XptM2MSecCryptoAlg_e cryptAlg;
1683    BCMD_CipherModeSelect_e cipherMode;
1684    BCMD_TerminationMode_e terminationMode;
1685    BCMD_IVSelect_e ivModeSelect;
1686    BCMD_SolitarySelect_e solitarySelect;
1687#else
1688    unsigned int cryptAlg;
1689    BHSM_ResidueMode_e residualMode = BHSM_ResidueMode_eUnscrambled;
1690#endif
1691    NEXUS_SecurityKeySource keySrc;
1692    bool bAVKeyladder = false;
1693    NEXUS_Security_P_KeySlotListNode *p;
1694
1695    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
1696
1697    if ( !keyHandle || !pSettings)
1698        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
1699
1700    p = NEXUS_Security_P_LocateNodeByKeyslot(keyHandle);
1701    p->algorithm = pSettings->algorithm;
1702
1703    BKNI_Memset(&configAlgorithmIO, 0, sizeof (configAlgorithmIO));
1704
1705    keySlotType = keyHandle->keyslotType;
1706    unKeySlotNum = keyHandle->keySlotNumber;
1707    keySrc = pSettings->keySource;
1708
1709#if HSM_IS_ASKM
1710    NEXUS_Security_GetHsmAlgorithmKeySetting(keyHandle, pSettings,
1711            &cryptAlg,
1712            &cipherMode,
1713            &terminationMode);
1714    ivModeSelect = pSettings->ivMode;
1715    solitarySelect = pSettings->solitarySelect;
1716#else
1717    NEXUS_Security_GetHsmAlgorithmKeySetting(keyHandle, pSettings, &cryptAlg, &residualMode);
1718#endif
1719
1720    rc = NEXUS_Security_GetHsmDestBlkType(p, pSettings->dest, &blockType);
1721    if (rc) return BERR_TRACE(rc);
1722
1723    switch (blockType) {
1724    case BCMD_KeyDestBlockType_eCA:
1725#if HSM_IS_ASKM
1726    case BCMD_KeyDestBlockType_eCPScrambler:
1727    case BCMD_KeyDestBlockType_eCPDescrambler:
1728#endif
1729        bConfigOddAndEven = (pSettings->keyDestEntryType == NEXUS_SecurityKeyType_eOddAndEven);
1730        break;
1731#if !HSM_IS_ASKM_40NM
1732    case BCMD_KeyDestBlockType_eRmx:
1733        bConfigOddAndEven = (pSettings->keyDestEntryType == NEXUS_SecurityKeyType_eOddAndEven);
1734        bConfigClear = true;
1735        break;
1736#endif
1737    default:
1738        break;
1739    }
1740
1741/*
1742    if (keyHandle->cryptoEngine==NEXUS_SecurityEngine_eCaCp)
1743#if !HSM_IS_ASKM_40NM
1744        bConfigClear = true;
1745#endif
1746*/
1747    /* if req. is for AV Keyladder, config only for KeyDestEntryType requested */
1748    if (keySrc == NEXUS_SecurityKeySource_eAvCPCW || keySrc == NEXUS_SecurityKeySource_eAvCW) {
1749        bConfigOddAndEven = false;
1750#if !HSM_IS_ASKM_40NM
1751        bConfigClear = false;
1752#endif
1753        bAVKeyladder = true;
1754    }
1755
1756#if !HSM_IS_ASKM_40NM
1757    if (!bAVKeyladder) /* keep the keySource setting for AV Keyladder */
1758        configAlgorithmIO.keySource = BCMD_KeyRamBuf_eFirstRam; /*BCMD_KeyRamBuf_eKey5KeyLadder2; */
1759    else {
1760#if HSM_IS_ASKM
1761        configAlgorithmIO.keySource = keySrc;
1762#else
1763        if (keySrc == NEXUS_SecurityKeySource_eAvCPCW)
1764            configAlgorithmIO.keySource = BCMD_KeyRamBuf_eReserved0;
1765        else
1766            configAlgorithmIO.keySource = BCMD_KeyRamBuf_eReserved1;
1767#endif
1768    }
1769#endif
1770    configAlgorithmIO.keyDestBlckType = blockType;
1771    if (bAVKeyladder) /* keep the KeyDestEntryType as requested for AV Keyladder */
1772        configAlgorithmIO.keyDestEntryType = NEXUS_Security_MapNexusKeyDestToHsm(keyHandle, pSettings->keyDestEntryType);
1773    else {
1774        if (bConfigOddAndEven) {
1775            configAlgorithmIO.keyDestEntryType = BCMD_KeyDestEntryType_eOddKey;
1776        } else {
1777            configAlgorithmIO.keyDestEntryType = NEXUS_Security_MapNexusKeyDestToHsm(keyHandle, pSettings->keyDestEntryType);
1778        }
1779    }
1780    configAlgorithmIO.caKeySlotType = keySlotType;
1781    configAlgorithmIO.unKeySlotNum = unKeySlotNum;
1782    if (keyHandle->cryptoEngine == NEXUS_SecurityEngine_eM2m) 
1783    {
1784        BKNI_Memset(&(configAlgorithmIO.cryptoAlg.m2mCryptAlg), 0, sizeof(configAlgorithmIO.cryptoAlg.m2mCryptAlg));
1785
1786        configAlgorithmIO.cryptoAlg.m2mCryptAlg.m2mSecAlg = cryptAlg;
1787#if HSM_IS_ASKM
1788        configAlgorithmIO.cryptoAlg.m2mCryptAlg.m2mCipherMode = cipherMode;
1789        configAlgorithmIO.cryptoAlg.m2mCryptAlg.TerminationAESCounterKeyMode = terminationMode;
1790        configAlgorithmIO.cryptoAlg.m2mCryptAlg.IVModeSelect = ivModeSelect;
1791        configAlgorithmIO.cryptoAlg.m2mCryptAlg.SolitarySelect = solitarySelect;
1792#else
1793        configAlgorithmIO.cryptoAlg.m2mCryptAlg.ucAESCounterKeyMode = residualMode;
1794#endif
1795        if (pSettings->operation == NEXUS_SecurityOperation_eEncrypt)
1796            configAlgorithmIO.cryptoAlg.m2mCryptAlg.ucAuthCtrl = BHSM_M2mAuthCtrl_eScramble;
1797        else if (pSettings->operation == NEXUS_SecurityOperation_eDecrypt)
1798            configAlgorithmIO.cryptoAlg.m2mCryptAlg.ucAuthCtrl = BHSM_M2mAuthCtrl_eDescramble;
1799        else
1800            configAlgorithmIO.cryptoAlg.m2mCryptAlg.ucAuthCtrl = BHSM_M2mAuthCtrl_ePassThrough;
1801
1802        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bEnableTimestamp = pSettings->enableTimestamps;
1803        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bMscCtrlSel = pSettings->mscBitSelect;
1804
1805#if HSM_IS_ASKM
1806        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bDisallowGG = pSettings->bDisallowGG;
1807        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bDisallowGR = pSettings->bDisallowGR;
1808        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bDisallowRG = pSettings->bDisallowRG;
1809        configAlgorithmIO.cryptoAlg.m2mCryptAlg.bDisallowRR = pSettings->bDisallowRR;
1810#endif
1811
1812        /*set key & IV to external if the algorithm is WMDRMPD*/
1813        if ((pSettings->algorithm == NEXUS_SecurityAlgorithm_eWMDrmPd) || (pSettings->algorithm == NEXUS_SecurityAlgorithm_eRc4)) {
1814            configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtKey = true;
1815            configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtIV = true;
1816        } else {
1817#ifdef NEXUS_SECURITY_EXT_KEY_IV
1818            configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtKey = pSettings->enableExtKey;
1819            configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtIV = pSettings->enableExtIv;
1820#else
1821            if ( (pSettings->enableExtKey) || (pSettings->enableExtIv)) {
1822                BDBG_ERR(("\nYou were trying to use external key or IV without turning on BSP_M2M_EXT_KEY_IV_SUPPORT\n" ));
1823                BDBG_ERR(("\nPlease rebuild nexus with BSP_M2M_EXT_KEY_IV_SUPPORT=ON\n" ));
1824                return NEXUS_NOT_SUPPORTED;
1825            }
1826
1827#endif
1828        }
1829
1830    } 
1831    else 
1832    {
1833        BKNI_Memset(&(configAlgorithmIO.cryptoAlg.caCryptAlg), 0, sizeof(configAlgorithmIO.cryptoAlg.caCryptAlg));
1834
1835        configAlgorithmIO.cryptoAlg.caCryptAlg.caSecAlg = cryptAlg;
1836#if HSM_IS_ASKM
1837#if HSM_IS_ASKM_40NM
1838        configAlgorithmIO.cryptoAlg.caCryptAlg.cipherDVBCSA2Mode = cipherMode;
1839#else
1840        configAlgorithmIO.cryptoAlg.caCryptAlg.cipherDVBMode = cipherMode;
1841#endif
1842        configAlgorithmIO.cryptoAlg.caCryptAlg.terminationMode = terminationMode;
1843        configAlgorithmIO.cryptoAlg.caCryptAlg.IVMode = ivModeSelect;
1844        configAlgorithmIO.cryptoAlg.caCryptAlg.solitaryMode = solitarySelect;
1845
1846#else
1847        if (cryptAlg != BCMD_XptSecCryptoAlg_eDvb)
1848            configAlgorithmIO.cryptoAlg.caCryptAlg.residueMode.residueMode = residualMode;
1849        else
1850            configAlgorithmIO.cryptoAlg.caCryptAlg.residueMode.dvbScrambleLevel = residualMode;
1851#endif
1852        configAlgorithmIO.cryptoAlg.caCryptAlg.bRestrictEnable = pSettings->bRestrictEnable;
1853        configAlgorithmIO.cryptoAlg.caCryptAlg.bGlobalEnable = pSettings->bGlobalEnable;
1854        configAlgorithmIO.cryptoAlg.caCryptAlg.ucMulti2KeySelect = pSettings->multi2KeySelect;
1855#if HSM_IS_ASKM_40NM
1856        configAlgorithmIO.cryptoAlg.caCryptAlg.keyOffset = pSettings->keyOffset;
1857        configAlgorithmIO.cryptoAlg.caCryptAlg.ivOffset = pSettings->ivOffset;
1858        configAlgorithmIO.cryptoAlg.caCryptAlg.ucMSCLengthSelect = pSettings->mscLengthSelect;
1859        configAlgorithmIO.cryptoAlg.caCryptAlg.customerType = (BCMD_XptKeyTableCustomerMode_e)pSettings->customerType;
1860        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA2keyCtrl = pSettings->dvbCsa2keyCtrl;
1861        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA2ivCtrl = pSettings->dvbCsa2ivCtrl;
1862        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA2modEnabled = pSettings->dvbCsa2modEnabled;
1863        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA3dvbcsaVar = pSettings->dvbCsa3dvbcsaVar;
1864        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA3permutation = pSettings->dvbCsa3permutation;
1865        configAlgorithmIO.cryptoAlg.caCryptAlg.DVBCSA3modXRC = pSettings->dvbCsa3modXRC;
1866#ifdef NEXUS_SECURITY_EXT_KEY_IV 
1867        configAlgorithmIO.cryptoAlg.caCryptAlg.bUseExtKey = pSettings->enableExtKey;
1868        configAlgorithmIO.cryptoAlg.caCryptAlg.bUseExtIV = pSettings->enableExtIv;
1869#else
1870        if ( (pSettings->enableExtKey) || (pSettings->enableExtIv)) 
1871        {
1872            BDBG_ERR(("\nYou were trying to use external key or IV without turning on BSP_M2M_EXT_KEY_IV_SUPPORT\n" ));
1873            BDBG_ERR(("\nPlease rebuild nexus with BSP_M2M_EXT_KEY_IV_SUPPORT=ON\n" ));
1874            return NEXUS_NOT_SUPPORTED;
1875        }
1876#endif
1877
1878#else
1879        configAlgorithmIO.cryptoAlg.caCryptAlg.bAtscMod = pSettings->bAtscModEnable;
1880        configAlgorithmIO.cryptoAlg.caCryptAlg.bAtscScrambleCtrl = pSettings->bScAtscMode;
1881        configAlgorithmIO.cryptoAlg.caCryptAlg.bGlobalDropPktCtrl = pSettings->bGlobalDropPktEnable;
1882        configAlgorithmIO.cryptoAlg.caCryptAlg.bRestrictDropPktCtrl = pSettings->bRestrictDropPktEnable;
1883        configAlgorithmIO.cryptoAlg.caCryptAlg.bGlobalRegOverwrite = pSettings->bGlobalRegionOverwrite;
1884        configAlgorithmIO.cryptoAlg.caCryptAlg.bRestrictScMod = pSettings->modifyScValue[NEXUS_SecurityPacketType_eRestricted];
1885        configAlgorithmIO.cryptoAlg.caCryptAlg.bGlobalScMod = pSettings->modifyScValue[NEXUS_SecurityPacketType_eGlobal];
1886#endif
1887
1888#if HSM_IS_ASKM
1889        configAlgorithmIO.cryptoAlg.caCryptAlg.bEncryptBeforeRave = pSettings->bEncryptBeforeRave;
1890#else
1891        configAlgorithmIO.cryptoAlg.caCryptAlg.bEncScPolarity = pSettings->bScPolarityEnable;
1892        configAlgorithmIO.cryptoAlg.caCryptAlg.bSynEnable = pSettings->bSynEnable;
1893        configAlgorithmIO.cryptoAlg.caCryptAlg.bCPDDisable = pSettings->bCPDDisable;
1894        configAlgorithmIO.cryptoAlg.caCryptAlg.bCPSDisable = pSettings->bCPSDisable;
1895#endif
1896
1897#if HSM_IS_ASKM_40NM_ZEUS_2_0
1898        configAlgorithmIO.cryptoAlg.caCryptAlg.bDropRregionPackets = pSettings->bRestrictSourceDropPktEnable;
1899        configAlgorithmIO.cryptoAlg.caCryptAlg.bGpipePackets2Rregion = pSettings->bRoutePipeToRestrictedRegion[NEXUS_SecurityPacketType_eGlobal];
1900        configAlgorithmIO.cryptoAlg.caCryptAlg.bRpipePackets2Rregion = pSettings->bRoutePipeToRestrictedRegion[NEXUS_SecurityPacketType_eRestricted];
1901#endif
1902#ifdef NEXUS_SECURITY_SC_VALUE
1903#if !HSM_IS_ASKM_40NM
1904        configAlgorithmIO.cryptoAlg.caCryptAlg.uScValue = g_scValues[pSettings->scValue[NEXUS_SecurityPacketType_eGlobal]];
1905        if (pSettings->scValue[NEXUS_SecurityPacketType_eRestricted] != NEXUS_SecurityAlgorithmScPolarity_eClear) {
1906            BDBG_WRN(("SC polarity cannot be differentiated by packet type on this chip.  Ignoring the attempt to set a non-global packet type."));
1907        }
1908#endif
1909#else
1910        if (pSettings->modifyScValue[NEXUS_SecurityPacketType_eGlobal] || pSettings->modifyScValue[NEXUS_SecurityPacketType_eRestricted]) {
1911            BDBG_ERR(("You were trying to set SC value without turning on BSP_SC_VALUE_SUPPORT"));
1912            BDBG_ERR(("Please rebuild nexus with BSP_SC_VALUE_SUPPORT=ON" ));
1913            return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1914        }
1915#endif
1916    }
1917
1918#if HSM_IS_ASKM
1919    /* Call BHSM_configKeySlotIDData() to set up ID part of  configuration odd key */
1920    configKeySlotIDDataIO.keyDestBlckType = blockType;
1921    if (bAVKeyladder) /* keep the KeyDestEntryType as requested for AV Keyladder */
1922        configKeySlotIDDataIO.keyDestEntryType = NEXUS_Security_MapNexusKeyDestToHsm(keyHandle, pSettings->keyDestEntryType);
1923    else {
1924        if (bConfigOddAndEven) {
1925            configKeySlotIDDataIO.keyDestEntryType = BCMD_KeyDestEntryType_eOddKey;
1926        } else {
1927            configKeySlotIDDataIO.keyDestEntryType = NEXUS_Security_MapNexusKeyDestToHsm(keyHandle, pSettings->keyDestEntryType);
1928        }
1929    }
1930#if HSM_IS_ASKM_40NM
1931    configKeySlotIDDataIO.keyDestIVType = BCMD_KeyDestIVType_eNoIV;
1932#endif
1933
1934    configKeySlotIDDataIO.unKeySlotNum = unKeySlotNum;
1935    configKeySlotIDDataIO.caKeySlotType = keySlotType;
1936    configKeySlotIDDataIO.CAVendorID = pSettings->caVendorID;
1937    configKeySlotIDDataIO.STBOwnerIDSelect = pSettings->otpId;
1938    configKeySlotIDDataIO.ModuleID = pSettings->askmModuleID;
1939#if HSM_IS_ASKM_40NM
1940    configKeySlotIDDataIO.key2Select = pSettings->key2Select;
1941#else
1942    configKeySlotIDDataIO.TestKey2Select = pSettings->testKey2Select;
1943#endif
1944
1945    rc = BHSM_ConfigKeySlotIDData(g_security.hsm, &configKeySlotIDDataIO);
1946    if (rc)
1947    {
1948        return BERR_TRACE(MAKE_HSM_ERR(rc));
1949    }
1950
1951#endif
1952    if (keyHandle->cryptoEngine != NEXUS_SecurityEngine_eM2m) 
1953    {
1954        NEXUS_Security_P_SetScValues(&configAlgorithmIO, pSettings, bConfigOddAndEven ? NEXUS_SecurityKeyType_eOdd : pSettings->keyDestEntryType );
1955    }
1956    rc = BHSM_ConfigAlgorithm(g_security.hsm, &configAlgorithmIO);
1957    if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
1958
1959#if HSM_IS_ASKM
1960
1961#ifdef NEXUS_SECURITY_EXT_KEY_IV
1962    /* We must send a dummy route key command for algorithm setting to take effect on 7420 family chips */
1963    if (keyHandle->cryptoEngine == NEXUS_SecurityEngine_eM2m)
1964    {
1965        if ( (configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtKey == true) ||
1966                (configAlgorithmIO.cryptoAlg.m2mCryptAlg.bUseExtIV == true))
1967        {
1968            BHSM_LoadRouteUserKeyIO_t loadRouteUserKeyIO;
1969            BKNI_Memset(&loadRouteUserKeyIO, 0, sizeof(loadRouteUserKeyIO));
1970            loadRouteUserKeyIO.bIsRouteKeyRequired = true;
1971            loadRouteUserKeyIO.keyDestBlckType = BCMD_KeyDestBlockType_eMem2Mem;
1972#if !HSM_IS_ASKM_40NM
1973            loadRouteUserKeyIO.keySource = BCMD_KeyRamBuf_eFirstRam;
1974#endif
1975            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e128;
1976            loadRouteUserKeyIO.bIsRouteKeyRequired = true;
1977            loadRouteUserKeyIO.keyDestEntryType = BCMD_KeyDestEntryType_eOddKey;
1978            loadRouteUserKeyIO.caKeySlotType = keySlotType;
1979            loadRouteUserKeyIO.unKeySlotNum = unKeySlotNum;
1980            loadRouteUserKeyIO.keyMode= BCMD_KeyMode_eRegular;
1981            rc = BHSM_LoadRouteUserKey (g_security.hsm, &loadRouteUserKeyIO);
1982            if (rc)
1983            {
1984                BDBG_ERR(("External Key/IV may not be enabled by OTP\n"));
1985                return BERR_TRACE(MAKE_HSM_ERR(rc));
1986            }
1987        }
1988    }
1989
1990#endif
1991#endif
1992
1993    if (bConfigOddAndEven) {
1994#if HSM_IS_ASKM
1995        /* Call BHSM_configKeySlotIDData() to set up ID part of  configuration odd key */
1996        configKeySlotIDDataIO.keyDestEntryType = BCMD_KeyDestEntryType_eEvenKey;
1997        rc = BHSM_ConfigKeySlotIDData(g_security.hsm, &configKeySlotIDDataIO);
1998        if (rc)
1999        {
2000            return BERR_TRACE(MAKE_HSM_ERR(rc));
2001        }
2002
2003#endif
2004        configAlgorithmIO.keyDestEntryType = BCMD_KeyDestEntryType_eEvenKey;
2005        if (keyHandle->cryptoEngine != NEXUS_SecurityEngine_eM2m) 
2006        {
2007            NEXUS_Security_P_SetScValues(&configAlgorithmIO, pSettings, NEXUS_SecurityKeyType_eEven );
2008        }
2009        rc = BHSM_ConfigAlgorithm(g_security.hsm, &configAlgorithmIO);
2010        if (rc) { return BERR_TRACE(MAKE_HSM_ERR(rc)); }
2011    }
2012
2013#if !HSM_IS_ASKM_40NM
2014    if (bConfigClear) {
2015#if HSM_IS_ASKM
2016        /* Call BHSM_configKeySlotIDData() to set up ID part of  configuration odd key */
2017#if HSM_IS_ASKM_40NM
2018        configKeySlotIDDataIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved2;
2019#else
2020        configKeySlotIDDataIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved0;
2021#endif
2022        rc = BHSM_ConfigKeySlotIDData(g_security.hsm, &configKeySlotIDDataIO);
2023        if (rc)
2024        {
2025            return BERR_TRACE(MAKE_HSM_ERR(rc));
2026        }
2027
2028        /* If destination block is CA and 65-nm platform, we need to alter mode word for clear key slot */
2029        /* to configure the SC bit modification for CaCp and send out a dummy LRUK command.  This */
2030        /* works only for 65-nm BSECK 2.0 and later.   */
2031
2032        if ( blockType == BCMD_KeyDestBlockType_eCA ) 
2033        {
2034            configAlgorithmIO.cryptoAlg.caCryptAlg.caSecAlg = BCMD_XptM2MSecCryptoAlg_eDes;
2035            configAlgorithmIO.cryptoAlg.caCryptAlg.IVMode = BCMD_IVSelect_eRegular;
2036#if HSM_IS_ASKM_40NM
2037            configAlgorithmIO.cryptoAlg.caCryptAlg.cipherDVBCSA2Mode = BCMD_CipherModeSelect_eECB;
2038            configAlgorithmIO.cryptoAlg.caCryptAlg.terminationMode = BCMD_TerminationMode_eCLEAR;
2039            configAlgorithmIO.cryptoAlg.caCryptAlg.solitaryMode = BCMD_SolitarySelect_eCLEAR;
2040#else
2041            configAlgorithmIO.cryptoAlg.caCryptAlg.cipherDVBMode = BCMD_CipherModeSelect_eECB;
2042            configAlgorithmIO.cryptoAlg.caCryptAlg.terminationMode = BCMD_TerminationMode_eClear;
2043            configAlgorithmIO.cryptoAlg.caCryptAlg.solitaryMode = BCMD_SolitarySelect_eClear;
2044#endif
2045            /* The following 2 settings are needed so that FW won't reject the key routing command */
2046            /* associated with this clear key slot for 65-nm platforms */
2047#if !HSM_IS_ASKM_40NM
2048            configAlgorithmIO.cryptoAlg.caCryptAlg.bRestrictEnable = false;
2049            configAlgorithmIO.cryptoAlg.caCryptAlg.bGlobalEnable = false;
2050#endif
2051        }
2052
2053#endif
2054
2055#if HSM_IS_ASKM_40NM
2056        configAlgorithmIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved2;
2057#else
2058        configAlgorithmIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved0;
2059#endif
2060        NEXUS_Security_P_SetScValues(&configAlgorithmIO, pSettings, NEXUS_SecurityKeyType_eClear );
2061        rc = BHSM_ConfigAlgorithm(g_security.hsm, &configAlgorithmIO);
2062        if (rc) 
2063        { 
2064            return BERR_TRACE(MAKE_HSM_ERR(rc)); 
2065        }
2066#if HSM_IS_ASKM
2067        /* Must call load key for algorithm setting to take effect */
2068        if ( blockType==BCMD_KeyDestBlockType_eCA )
2069        {
2070            BHSM_LoadRouteUserKeyIO_t loadRouteUserKeyIO;
2071            BKNI_Memset(&loadRouteUserKeyIO, 0, sizeof(loadRouteUserKeyIO));
2072#if !HSM_IS_ASKM_40NM
2073            loadRouteUserKeyIO.keySource = BCMD_KeyRamBuf_eFirstRam;
2074#endif
2075            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e128;
2076            loadRouteUserKeyIO.bIsRouteKeyRequired = true;
2077#if HSM_IS_ASKM_40NM
2078            loadRouteUserKeyIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved2;
2079            loadRouteUserKeyIO.keyDestIVType    = BCMD_KeyDestIVType_eNoIV;
2080#else
2081            loadRouteUserKeyIO.keyDestEntryType = BCMD_KeyDestEntryType_eReserved0;
2082#endif
2083            loadRouteUserKeyIO.caKeySlotType = keySlotType;
2084            loadRouteUserKeyIO.unKeySlotNum = unKeySlotNum;
2085            loadRouteUserKeyIO.keyMode= BCMD_KeyMode_eRegular;
2086            loadRouteUserKeyIO.keyDestBlckType = blockType;
2087            rc = BHSM_LoadRouteUserKey (g_security.hsm, &loadRouteUserKeyIO);
2088        if (rc) 
2089        { 
2090                BDBG_ERR(("Configure Clear key failed.  You may need to update new versions of BSECK"));
2091                /*return BERR_TRACE(MAKE_HSM_ERR(rc));*/
2092                rc = NEXUS_SUCCESS; /* Ignore error for now */
2093            }
2094        }
2095#endif
2096
2097    }
2098#endif
2099
2100    return rc;
2101}
2102
2103void NEXUS_Security_GetDefaultClearKey(NEXUS_SecurityClearKey *pClearKey)
2104{
2105    BKNI_Memset(pClearKey, 0, sizeof(*pClearKey));
2106}
2107
2108NEXUS_Error NEXUS_Security_LoadClearKey(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityClearKey * pClearKey)
2109{
2110    NEXUS_Error rc = NEXUS_SUCCESS;
2111    BCMD_KeyDestBlockType_e   blockType;
2112    BCMD_KeyDestEntryType_e   entryType = BCMD_KeyDestEntryType_eOddKey;
2113    BHSM_LoadRouteUserKeyIO_t loadRouteUserKeyIO;
2114#if HSM_IS_ASKM_40NM
2115    BCMD_KeyDestIVType_e      ivType;
2116#endif
2117    NEXUS_Security_P_KeySlotListNode *p;
2118
2119    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
2120#if HSM_IS_ASKM_40NM
2121    blockType = BCMD_KeyDestBlockType_eCA;
2122#else
2123    blockType = BCMD_KeyDestBlockType_eRmx;
2124#endif
2125
2126    p = NEXUS_Security_P_LocateNodeByKeyslot(keyHandle);
2127    NEXUS_Security_GetHsmDestBlkType(p, pClearKey->dest, &blockType);
2128    NEXUS_Security_GetHsmDestEntrykType(pClearKey->keyEntryType, &entryType);
2129#if HSM_IS_ASKM_40NM
2130    NEXUS_Security_GetHsmDestIVType(pClearKey->keyIVType, &ivType);
2131#endif
2132
2133        BKNI_Memset(&loadRouteUserKeyIO, 0, sizeof(loadRouteUserKeyIO));
2134    if (pClearKey->keySize) {
2135#if !HSM_IS_ASKM_40NM
2136        loadRouteUserKeyIO.keySource = BCMD_KeyRamBuf_eFirstRam;
2137#endif
2138        if (pClearKey->keySize==8)
2139            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e64;
2140        else if (pClearKey->keySize==16)
2141            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e128;
2142        else if (pClearKey->keySize==24)
2143            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e192;
2144#if HSM_IS_ASKM_40NM_ZEUS_2_0
2145        else if (pClearKey->keySize==32)
2146            loadRouteUserKeyIO.keySize.eKeySize = BCMD_KeySize_e256;
2147#endif
2148        else {
2149            return BERR_TRACE(NEXUS_INVALID_PARAMETER);
2150        }
2151        BKNI_Memset(loadRouteUserKeyIO.aucKeyData, 0, sizeof(loadRouteUserKeyIO.aucKeyData));
2152        BKNI_Memcpy(loadRouteUserKeyIO.aucKeyData, pClearKey->keyData, pClearKey->keySize);
2153        loadRouteUserKeyIO.bIsRouteKeyRequired = true;
2154        loadRouteUserKeyIO.keyDestBlckType = blockType;
2155        loadRouteUserKeyIO.keyDestEntryType = entryType;
2156        loadRouteUserKeyIO.caKeySlotType = keyHandle->keyslotType;
2157        loadRouteUserKeyIO.unKeySlotNum = keyHandle->keySlotNumber;
2158        loadRouteUserKeyIO.keyMode= BCMD_KeyMode_eRegular;
2159#if HSM_IS_ASKM_40NM
2160        loadRouteUserKeyIO.keyDestIVType = ivType;
2161#endif
2162#if HSM_IS_ASKM_40NM_ZEUS_2_0
2163#ifdef NEXUS_SECURITY_SC_VALUE
2164        loadRouteUserKeyIO.GpipeSC01Val = g_scValues[pClearKey->sc01Polarity[NEXUS_SecurityPacketType_eGlobal]];
2165        loadRouteUserKeyIO.RpipeSC01Val = g_scValues[pClearKey->sc01Polarity[NEXUS_SecurityPacketType_eRestricted]];
2166#endif
2167#endif
2168        rc = BHSM_LoadRouteUserKey(g_security.hsm, &loadRouteUserKeyIO);
2169        if (rc) {
2170            return BERR_TRACE(MAKE_HSM_ERR(rc));
2171        }
2172    }
2173
2174    return NEXUS_SUCCESS;
2175}
2176
2177NEXUS_KeySlotHandle NEXUS_Security_AllocateKeySlot(const NEXUS_SecurityKeySlotSettings *pSettings)
2178{
2179    NEXUS_KeySlotHandle pKeyHandle = NULL;
2180
2181    if (pSettings) {
2182        switch (pSettings->keySlotEngine) {
2183        case NEXUS_SecurityEngine_eM2m:
2184            BDBG_MSG(("Allocating M2M keyslot"));
2185            if (NEXUS_Security_AllocateM2mKeySlot(&pKeyHandle))
2186                return NULL;
2187            break;
2188        case NEXUS_SecurityEngine_eRmx:
2189        case NEXUS_SecurityEngine_eCaCp:
2190            BDBG_MSG(("Allocating RMX/CaCp keyslot"));
2191            if (NEXUS_Security_AllocateKeySlotForType(&pKeyHandle,pSettings->keySlotEngine,NEXUS_Security_MapNexusKeySlotTypeToHsm(pSettings->keySlotType,pSettings->keySlotEngine)))
2192                return NULL;
2193            break;
2194        case NEXUS_SecurityEngine_eCa:
2195            BDBG_MSG(("Allocating CA (or other) keyslot"));
2196            if (NEXUS_Security_AllocateKeySlotForType(&pKeyHandle,pSettings->keySlotEngine,NEXUS_Security_MapNexusKeySlotTypeToHsm(pSettings->keySlotType,pSettings->keySlotEngine)))
2197                return NULL;
2198            break;
2199        default:
2200            BDBG_WRN(("Unsupported key type"));
2201            return NULL;
2202        }
2203    }
2204    {
2205        NEXUS_Security_P_KeySlotListNode *node;
2206        node = BKNI_Malloc(sizeof(*node));
2207        if (node) {
2208            BKNI_Memset(node,0,sizeof(*node));
2209            node->handle = pKeyHandle;
2210            BLST_S_INIT(&node->pidchannels);
2211            BLST_S_INSERT_HEAD(&g_security.keyslots, node, next);
2212        } else {
2213            BDBG_WRN(("Unable to track handle %p",pKeyHandle));
2214        }
2215    }
2216    NEXUS_SECURITY_DUMP_KEYSLOTS;
2217    return pKeyHandle;
2218}
2219
2220void NEXUS_Security_FreeKeySlot(NEXUS_KeySlotHandle keyHandle)
2221{
2222    BERR_Code rc = 0;
2223
2224    BDBG_OBJECT_ASSERT(keyHandle, NEXUS_KeySlot);
2225    switch (keyHandle->cryptoEngine)
2226    {
2227        case NEXUS_SecurityEngine_eCa:
2228        case NEXUS_SecurityEngine_eCaCp:
2229            BDBG_MSG(("Freeing CA keyslot (%d)", keyHandle->keySlotNumber));
2230            rc = BHSM_FreeCAKeySlot(g_security.hsm, keyHandle->pidChannel, BHSM_PidChannelType_ePrimary, keyHandle->keyslotType, keyHandle->keySlotNumber);
2231            if (rc) BDBG_ERR(("Error (%d) freeing CA keyslot", rc));
2232            break;
2233        case NEXUS_SecurityEngine_eM2m:
2234            BDBG_MSG(("Freeing m2m keyslot (%d)", keyHandle->keySlotNumber));
2235            rc = BHSM_FreeM2MKeySlot(g_security.hsm, keyHandle->keySlotNumber);
2236            if (rc) BDBG_ERR(("Error (%d) freeing M2M keyslot", rc));
2237            break;
2238        case NEXUS_SecurityEngine_eCp:
2239            BDBG_MSG(("Freeing cp keyslot"));
2240            BDBG_WRN(("CP keyslots are not currently supported"));
2241            rc = NEXUS_INVALID_PARAMETER; /* set an error so we don't decrease the power management refcount */
2242            break;
2243        case NEXUS_SecurityEngine_eRmx:
2244            BDBG_MSG(("Freeing rmx keyslot"));
2245            rc = BHSM_FreeCAKeySlot(g_security.hsm, keyHandle->pidChannel, BHSM_PidChannelType_ePrimary, keyHandle->keyslotType, keyHandle->keySlotNumber);
2246            if (rc) BDBG_ERR(("Error (%d) freeing CA keyslot", rc));
2247            break;
2248        default:
2249            break;
2250    }
2251    if (!rc)
2252        NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, false);
2253
2254    {
2255        NEXUS_Security_P_KeySlotListNode *p;
2256        for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
2257            if (p->handle == keyHandle) {
2258                NEXUS_Security_P_PidChannelListNode *q;
2259                while ((q=BLST_S_FIRST(&p->pidchannels))) {
2260                    BDBG_MSG(("%s: removing pidchannel %d from keyslot %p",__FUNCTION__,q->pidchannel,p->handle));
2261                    NEXUS_Security_RemovePidChannelFromKeySlot(p->handle, q->pidchannel);
2262                }
2263                BLST_S_REMOVE(&g_security.keyslots,p,NEXUS_Security_P_KeySlotListNode,next);
2264                BKNI_Free(p);
2265                break;
2266            }
2267        }
2268    }
2269
2270    NEXUS_SECURITY_DUMP_KEYSLOTS;
2271
2272    NEXUS_P_Core_FreeKeySlotHandle(keyHandle);
2273}
2274
2275void NEXUS_Security_GetDefaultMulti2Settings(NEXUS_SecurityMulti2Settings *pSettings /* [out] */ )
2276{
2277    if (pSettings) {
2278        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
2279    }
2280}
2281
2282NEXUS_Error NEXUS_Security_ConfigMulti2(NEXUS_KeySlotHandle keyHandle, const NEXUS_SecurityMulti2Settings *pSettings)
2283{
2284    NEXUS_Error rc = NEXUS_SUCCESS;
2285    BHSM_ConfigMulti2IO_t config_multi2;
2286
2287    BSTD_UNUSED(keyHandle);
2288
2289    BKNI_Memset(&config_multi2, 0, sizeof(config_multi2));
2290    config_multi2.ucMulti2RndCnt = pSettings->multi2Rounds;
2291    BKNI_Memcpy(config_multi2.aucMulti2SysKey, pSettings->multi2SysKey, 32);
2292    config_multi2.ucSysKeyDest = pSettings->multi2KeySelect;
2293    BHSM_ConfigMulti2(g_security.hsm, &config_multi2);
2294    if (config_multi2.unStatus != 0) {
2295        BDBG_ERR(("NEXUS_Security_ConfigMulti2: Error configuring Multi2 (0x%02x)", config_multi2.unStatus));
2296        rc = NEXUS_INVALID_PARAMETER;
2297    }
2298
2299    return rc;
2300}
2301
2302NEXUS_Error NEXUS_SecurityModule_Standby_priv(bool enabled, const NEXUS_StandbySettings *pSettings)
2303{
2304#if NEXUS_POWER_MANAGEMENT
2305    BERR_Code rc;
2306    BSTD_UNUSED(pSettings);
2307
2308    if (enabled) {
2309        if (pSettings->mode!=NEXUS_StandbyMode_eDeepSleep) { /* not S3 */
2310            /* NEXUS_PowerManagement_SetCoreState is called when keyslots are allocated and free'd.
2311               in non-S3, this does not have to occur, so we power down as many times as the number of keyslots opened */
2312            NEXUS_Security_P_KeySlotListNode *p = NULL;
2313            for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
2314                NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, false);
2315            }
2316           
2317        }
2318        else {
2319            /* enforce that apps free keyslots before standby and re-configure them after resume.
2320               this also takes care of NEXUS_PowerManagement_SetCoreState */
2321            if (BLST_S_FIRST(&g_security.keyslots)) {
2322                BDBG_ERR(("Keyslots must be freed before entering S3 standby"));
2323                return BERR_TRACE(NEXUS_NOT_SUPPORTED);
2324            }
2325            NEXUS_Security_P_UninitHsm();
2326            g_security.hsm = NULL;
2327        }
2328       
2329    }
2330    else {
2331        if (g_security.hsm) { /* not S3 */
2332            NEXUS_Security_P_KeySlotListNode *p = NULL;
2333            for (p=BLST_S_FIRST(&g_security.keyslots);p!=NULL;p=BLST_S_NEXT(p,next)) {
2334                NEXUS_PowerManagement_SetCoreState(NEXUS_PowerManagementCore_eHsm, true);
2335            }
2336        }
2337        else {
2338            rc = NEXUS_Security_P_InitHsm(&g_security.settings);
2339            if (rc) { return BERR_TRACE(NEXUS_NOT_SUPPORTED); }
2340        }
2341    }
2342    return NEXUS_SUCCESS;
2343#else
2344    BSTD_UNUSED(pSettings);
2345    BSTD_UNUSED(enabled);
2346    return NEXUS_SUCCESS;
2347#endif
2348}
2349
2350/* This function is dangerous and not meant for general use. It is needed for
2351 test code that needs the HSM handle. It must be extern'd. */
2352void b_get_hsm(BHSM_Handle *hsm)
2353{
2354    *hsm = g_security.hsm;
2355}
2356void b_get_reg(BREG_Handle *reg)
2357{
2358    *reg = g_pCoreHandles->reg;
2359}
2360void b_get_int(BINT_Handle *bint)
2361{
2362    *bint = g_pCoreHandles->bint;
2363}
2364void b_get_chp(BCHP_Handle *chp)
2365{
2366    *chp = g_pCoreHandles->chp;
2367}
Note: See TracBrowser for help on using the repository browser.