source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_keyslot_priv.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 12.8 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2004-2010, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bsettop_keyslot_priv.c $
11 * $brcm_Revision: 13 $
12 * $brcm_Date: 6/10/10 2:45p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_keyslot_priv.c $
19 *
20 * 13   6/10/10 2:45p mphillip
21 * SW7550-380: Enable non-DMA PVR encryption for 7550 and similar
22 * platforms
23 *
24 * 12   6/3/10 5:11p mward
25 * SW7400-2786:  For DivX DRM under Nexus on 7400/7403, pass a DMA handle
26 * for use by bdrm_memory_crypt().
27 *
28 * 11   12/9/09 12:03p gmohile
29 * SW7408-1 : Add 7408 support
30 *
31 * 10   8/25/09 12:36p erickson
32 * SW7420-228: fix warnings
33 *
34 * 9   7/10/09 6:18p atruong
35 * PR55169: NEXUS/HSM PI support for 7420A1
36 *
37 * 8   6/15/09 5:07p jtna
38 * PR43001: add support for TTS+encryption record/playback
39 *
40 * 7   3/31/09 7:31p katrep
41 * PR53733: MSDRM_PD_HWDECRYPT support,moved msdrm pd compile to settop
42 * api from nexus
43 *
44 * 6   3/9/09 6:59p nickh
45 * PR52996: Fix compilation errors when NEXUS_HAS_SECURITY is disabled
46 *
47 * 5   2/26/09 2:53p erickson
48 * PR49584: add a dma-based memory bandwidth stress test feature
49 *
50 * 4   12/24/08 11:54a mphillip
51 * PR49607: Allow keyslot to be configured based on keyladder options
52 *
53 * 3   8/13/08 12:58p mphillip
54 * PR40027: Add CBC support to keyslot allocation
55 *
56 * 2   7/3/08 12:21p erickson
57 * PR39978: allow security to be optional
58 *
59 * 1   6/26/08 6:22p mphillip
60 * PR42901: Encrypted PVR playback support
61 *
62 *
63 *******************************************************************************/
64
65#include "bsettop_impl.h"
66
67#if NEXUS_HAS_DMA
68#include "nexus_dma.h"
69#endif
70#include "nexus_memory.h"
71#if NEXUS_HAS_SECURITY
72#include "nexus_security.h"
73#if NEXUS_HAS_KEYLADDER_SUPPORT
74#include "nexus_keyladder.h"
75#endif
76#endif
77#if B_HAS_MSDRM_PD && MSDRM_PD_HWDECRYPT
78#include "drmcore.h"
79#endif
80
81#if B_HAS_DIVX_DRM && (BCHP_CHIP==7400) || (BCHP_CHIP==7403)
82#include "bdrm_decrypt.h"
83#endif
84
85#if NEXUS_HAS_DMA
86struct bdma g_dma = {NULL};
87#endif
88
89BDBG_MODULE(dma);
90
91void bdma_p_init()
92{
93#if NEXUS_HAS_DMA
94    NEXUS_DmaSettings dmaSettings;
95
96    NEXUS_Dma_GetDefaultSettings(&dmaSettings);
97    dmaSettings.endianMode = NEXUS_DmaEndianMode_eLittle; /* TODO: endianness */
98    dmaSettings.swapMode = NEXUS_DmaSwapMode_eNone;
99
100    g_dma.hDma = NEXUS_Dma_Open(0, &dmaSettings);
101    if (g_dma.hDma == NULL) {
102        BDBG_ERR(("Unable to open DMA"));
103        return;
104    }
105#if B_HAS_MSDRM_PD && MSDRM_PD_HWDECRYPT
106    bdrm_set_dma_handle(g_dma.hDma);
107#endif
108#if B_HAS_DIVX_DRM && (BCHP_CHIP==7400) || (BCHP_CHIP==7403)
109        bdrm_divx_set_dma_handle(g_dma.hDma);
110#endif
111#endif   
112}
113
114void bdma_p_uninit()
115{
116#if NEXUS_HAS_DMA
117    if (g_dma.hDma) {
118        NEXUS_Dma_Close(g_dma.hDma);
119        g_dma.hDma = NULL;
120    }
121#if B_HAS_MSDRM_PD && MSDRM_PD_HWDECRYPT
122    bdrm_set_dma_handle(NULL);
123#endif
124#if B_HAS_DIVX_DRM && (BCHP_CHIP==7400) || (BCHP_CHIP==7403)
125        bdrm_divx_set_dma_handle(NULL);
126#endif
127#endif
128}
129
130NEXUS_KeySlotHandle b_keyslot_m2m_allocate(const bencryption_params *encryption, bool encrypt, bool timestamp)
131{
132#if NEXUS_HAS_SECURITY
133    NEXUS_Error rc;
134    NEXUS_KeySlotHandle pKeySlot = NULL;
135    NEXUS_SecurityKeySlotSettings keySettings;
136    NEXUS_SecurityAlgorithmSettings algSettings;
137    NEXUS_SecurityClearKey key;
138
139    NEXUS_Security_GetDefaultAlgorithmSettings(&algSettings);
140    switch (encryption->type) {
141    case bencryption_type_aes:
142        BDBG_MSG(("b_keyslot_m2m_allocate: Creating AES keyslot"));
143        algSettings.algorithm = NEXUS_SecurityAlgorithm_eAes;
144        break;
145    case bencryption_type_des:
146        BDBG_MSG(("b_keyslot_m2m_allocate: Creating DES keyslot"));
147        algSettings.algorithm = NEXUS_SecurityAlgorithm_eDes;
148        break;
149    case bencryption_type_3des:
150        BDBG_MSG(("b_keyslot_m2m_allocate: Creating 3DES keyslot"));
151        algSettings.algorithm = NEXUS_SecurityAlgorithm_e3DesAba;
152        break;
153    default:
154        BDBG_MSG(("b_keyslot_m2m_allocate: Unsupported encryption type: %d",encryption->type));
155        goto error;
156    }
157
158    NEXUS_Security_GetDefaultKeySlotSettings(&keySettings);
159#if NEXUS_HAS_DMA
160    keySettings.keySlotEngine = NEXUS_SecurityEngine_eM2m;
161#else
162    keySettings.keySlotEngine = NEXUS_SecurityEngine_eCp;
163#endif
164    pKeySlot = NEXUS_Security_AllocateKeySlot(&keySettings);
165    if (!pKeySlot) {
166        BDBG_ERR(("b_keyslot_m2m_allocate: Unable to allocate m2m keyslot"));
167        goto error;
168    }
169
170    algSettings.algorithmVar = encryption->blockmode == bcrypto_blockmode_cbc ? NEXUS_SecurityAlgorithmVariant_eCbc : NEXUS_SecurityAlgorithmVariant_eEcb;
171    algSettings.terminationMode = NEXUS_SecurityTerminationMode_eClear;
172#if NEXUS_HAS_DMA
173    algSettings.operation = encrypt ? NEXUS_SecurityOperation_eEncrypt : NEXUS_SecurityOperation_eDecrypt;
174#else
175    algSettings.dest = encrypt ? NEXUS_SecurityAlgorithmConfigDestination_eCps : NEXUS_SecurityAlgorithmConfigDestination_eCpd;
176#endif
177    algSettings.enableTimestamps = timestamp;
178    rc = NEXUS_Security_ConfigAlgorithm(pKeySlot, &algSettings);
179    if (rc != 0) {
180        BDBG_ERR(("b_keyslot_m2m_allocate: Unable to configure m2m algorithm"));
181        goto error_keyslot;
182    }
183
184    if (encryption->key_ladder) {
185#if NEXUS_HAS_KEYLADDER_SUPPORT
186        bcrypto_keyladder_data *keyladder_data = (bcrypto_keyladder_data *)encryption->long_key;
187        NEXUS_SecurityEncryptedSessionKey key3;
188        NEXUS_SecurityEncryptedControlWord key4;
189
190        if (encryption->key_length != 8*sizeof(bcrypto_keyladder_data)) {
191            BDBG_ERR(("b_keyslot_m2m_allocate: Invalid keyladder_data size"));
192            goto error_keyslot;
193        }
194        if (!keyladder_data) {
195            BDBG_ERR(("b_keyslot_m2m_allocate: No keyladder data provided!"));
196            goto error_keyslot;
197        }
198
199        if (keyladder_data->keyladder_key != bcrypto_keyladder_key_4 && keyladder_data->keyladder_key != bcrypto_keyladder_key_5) {
200            BDBG_ERR(("b_keyslot_m2m_allocate: Unsupported keyladder key"));
201            goto error_keyslot;
202        }
203
204        key3.keyladderID = NEXUS_SecurityKeyladderID_eA;
205        key3.keyladderType = NEXUS_SecurityKeyladderType_e3Des;
206        switch (keyladder_data->rootkey_src) {
207        case bcrypto_rootkey_cust_key:
208            key3.rootKeySrc = NEXUS_SecurityRootKeySrc_eCuskey;
209            break;
210        case bcrypto_rootkey_otp_a:
211            key3.rootKeySrc = NEXUS_SecurityRootKeySrc_eOtpKeyA;
212            break;
213        case bcrypto_rootkey_otp_b:
214            key3.rootKeySrc = NEXUS_SecurityRootKeySrc_eOtpKeyB;
215            break;
216        case bcrypto_rootkey_otp_c:
217            key3.rootKeySrc = NEXUS_SecurityRootKeySrc_eOtpKeyC;
218            break;
219        default:
220            BDBG_ERR(("b_keyslot_m2m_allocate: Unsupported keyladder root key source"));
221            goto error_keyslot;
222        }
223        switch (keyladder_data->swizzle) {
224        case bcrypto_swizzle_none:
225            key3.swizzleType = NEXUS_SecuritySwizzleType_eNone;
226            break;
227        case bcrypto_swizzle_0:
228            key3.swizzleType = NEXUS_SecuritySwizzleType_eSwizzle0;
229            break;
230        case bcrypto_swizzle_1:
231        default:
232            BDBG_ERR(("b_keyslot_m2m_allocate: Unsupported swizzle"));
233            goto error_keyslot;
234        }
235        key3.keyEntryType = NEXUS_SecurityKeyType_eOdd;
236        key3.operation = keyladder_data->gen_key_decrypt ? NEXUS_SecurityOperation_eDecrypt : NEXUS_SecurityOperation_eEncrypt;
237        key3.cusKeyL = keyladder_data->key_cust_low;
238        key3.cusKeyH = keyladder_data->key_cust_high;
239        key3.cusKeyVarL = keyladder_data->key_var_low;
240        key3.cusKeyVarH = keyladder_data->key_var_high;
241        BKNI_Memcpy((void *)(key3.keyData),
242                    (void *)(keyladder_data->odd_in_3),
243                    24);
244        key3.bRouteKey = false;
245
246        if (NEXUS_Security_GenerateSessionKey(pKeySlot, &key3) != 0) {
247            BDBG_ERR(("b_keyslot_m2m_allocate: Generate key3 failed"));
248            goto error_keyslot;
249        }
250
251        key4.keyladderID = NEXUS_SecurityKeyladderID_eA;
252        key4.keyladderType = NEXUS_SecurityKeyladderType_e3Des;
253        key4.keySize = 16;
254        key4.keyEntryType = NEXUS_SecurityKeyType_eOdd;
255        key4.operation = keyladder_data->gen_key_decrypt ? NEXUS_SecurityOperation_eDecrypt : NEXUS_SecurityOperation_eEncrypt;
256        key4.bRouteKey = keyladder_data->keyladder_key == bcrypto_keyladder_key_4 ? true : false;
257        BKNI_Memcpy((void *)(key4.keyData),
258                    (void *)(keyladder_data->odd_in_4),
259                    24);
260
261        if (NEXUS_Security_GenerateControlWord(pKeySlot, &key4) != 0) {
262            BDBG_ERR(("b_keyslot_m2m_allocate: Generate key4 failed"));
263            goto error_keyslot;
264        }
265
266        if (keyladder_data->keyladder_key == bcrypto_keyladder_key_5) {
267            /* Route Key 5 */
268            BDBG_ERR(("key5 ***NYI***"));
269        }
270#else
271        BDBG_ERR(("b_keyslot_m2m_allocate: Keyladder support is not enabled"));
272        goto error_keyslot;
273#endif
274    } else {
275        key.keySize = encryption->key_length/8;
276        key.keyEntryType = NEXUS_SecurityKeyType_eOdd; /* clear key */
277        BKNI_Memcpy(key.keyData,encryption->key,key.keySize);
278        if (NEXUS_Security_LoadClearKey(pKeySlot, &key) != 0) {
279            BDBG_ERR(("b_keyslot_m2m_allocate: Unable to load m2m key data"));
280            goto error_keyslot;
281        }
282    }
283
284    if (encryption->blockmode == bcrypto_blockmode_cbc) {
285        key.keyEntryType = NEXUS_SecurityKeyType_eIv;
286        if (encryption->type == bencryption_type_aes) {
287            key.keySize = 16;
288            BKNI_Memcpy(key.keyData,encryption->iv,key.keySize);
289        } else {
290            key.keySize = 16; /* We have to lie for alignment reasons */
291
292            /* This also means that the IV needs to be loaded in the second 8-byte
293             * block of the data, not the first, and the first part needs to be
294             * zeroed. */
295            BKNI_Memcpy(&key.keyData[8],encryption->iv,8);
296            BKNI_Memset(key.keyData,0,8);
297        }
298        if (NEXUS_Security_LoadClearKey(pKeySlot, &key) != 0) {
299            BDBG_ERR(("b_keyslot_m2m_allocate: Unable to load m2m IV data"));
300            b_keyslot_m2m_free(pKeySlot);
301            return NULL;
302        }
303    }
304
305    BDBG_MSG(("b_keyslot_m2m_allocateSuccessfully created keyslot"));
306    return pKeySlot;
307#else
308    BSTD_UNUSED(encryption);
309    BSTD_UNUSED(encrypt);
310    BSTD_UNUSED(timestamp);
311    BSETTOP_ERROR(berr_not_supported);
312    return NULL;
313#endif
314#if NEXUS_HAS_SECURITY
315error_keyslot:
316    b_keyslot_m2m_free(pKeySlot);
317error:
318#endif
319    return NULL;
320}
321
322void b_keyslot_m2m_free(NEXUS_KeySlotHandle pHandle)
323{
324#if NEXUS_HAS_SECURITY
325    if (pHandle) {
326        BDBG_MSG(("b_keyslot_m2m_free: Freeing keyslot"));
327        NEXUS_Security_FreeKeySlot(pHandle);
328    }
329#else
330    BSTD_UNUSED(pHandle);
331#endif
332}
333
334/***************
335* PR 49584: The following is stress-test code which soaks up all memory bandwidth using M2M DMA
336* export mem_stress=y to activate this feature.
337**/
338
339#if NEXUS_HAS_DMA
340static struct {
341    NEXUS_DmaJobHandle job;
342    uint64_t totalCopied;
343    void *mem;
344    unsigned size;
345    unsigned lastGbCopied;
346} g_memStress;
347
348static void bdma_p_mem_stress_callback(void *context, int param)
349{
350    NEXUS_DmaJobBlockSettings blockSettings;
351    NEXUS_Error rc;
352
353    BSTD_UNUSED(context);
354    if (param) {
355        unsigned gbCopied;
356        g_memStress.totalCopied += g_memStress.size;
357        gbCopied = (unsigned)(g_memStress.totalCopied / 1024 / 1024 / 1024);
358        if (g_memStress.lastGbCopied != gbCopied) {
359            BDBG_WRN(("mem_stress %d GB copied", gbCopied));
360            g_memStress.lastGbCopied = gbCopied;
361        }
362    }
363
364    NEXUS_DmaJob_GetDefaultBlockSettings(&blockSettings);
365    blockSettings.pSrcAddr = g_memStress.mem;
366    blockSettings.pDestAddr = g_memStress.mem;
367    blockSettings.blockSize = g_memStress.size;
368    NEXUS_DmaJob_SetBlockSettings(g_memStress.job, 0, &blockSettings);
369
370    rc = NEXUS_DmaJob_Start(g_memStress.job);
371    if (rc) rc = BERR_TRACE(rc);
372}
373
374void bdma_p_mem_stress(void)
375{
376    NEXUS_DmaJobSettings jobSettings;
377    NEXUS_Error rc;
378
379    NEXUS_DmaJob_GetDefaultSettings(&jobSettings);
380    jobSettings.numBlocks = 1;
381    jobSettings.completionCallback.callback = bdma_p_mem_stress_callback;
382    jobSettings.completionCallback.param = 1;
383    g_memStress.job = NEXUS_DmaJob_Create(g_dma.hDma, &jobSettings);
384
385    g_memStress.size = 10 * 1024 * 1024;
386    rc = NEXUS_Memory_Allocate(g_memStress.size, NULL, &g_memStress.mem);
387    if (rc) {
388        rc = BERR_TRACE(rc);
389        return;
390    }
391
392    /* kickstart the callback, then let it run forever */
393    bdma_p_mem_stress_callback(NULL, 0);
394}
395#endif
396
397
Note: See TracBrowser for help on using the repository browser.