source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_stream_encryption.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: 14.8 KB
Line 
1/***************************************************************************
2 *         Copyright (c) 2003-2009, 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_stream_encryption.c $
11 * $brcm_Revision: 4 $
12 * $brcm_Date: 1/7/09 4:04p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_stream_encryption.c $
19 *
20 * 4   1/7/09 4:04p mphillip
21 * PR50093: Add Multi2 support to the nexus shim
22 *
23 * 3   12/24/08 11:57a jgarrett
24 * PR 50703: Allowing security module to be absent
25 *
26 * 2   7/23/08 9:48a erickson
27 * PR45058: fix static array overrun bug
28 *
29 * 1   7/2/08 5:11p vishk
30 * PR 40020: bsettop_stream (crypto, network decryption): Develop
31 * SettopAPI-to-Nexus shim layer
32 *
33 ***************************************************************************/
34
35#include "bsettop_impl.h"
36#include <string.h>
37
38
39BDBG_MODULE(stream_encryption);
40
41
42void bencryption_params_init(bencryption_params *encryption)
43{
44        if (encryption) {
45                BKNI_Memset(encryption, 0, sizeof(*encryption));
46                encryption->pid = 0x1fff; /* default for bstream_set_encryption usage is to apply to all pids unless the pid is set */
47        }
48}
49
50bresult bstream_p_lookup_pid_info(bstream_t stream, unsigned short pid, unsigned *pid_channel, NEXUS_KeySlotHandle *KeySlotHandle, unsigned int *index)
51{
52        int i;
53        NEXUS_PidChannelStatus Status;
54
55        for (i=0;i<BSETTOP_MAX_PIDS;i++) {
56                /* Check the implementation of pid != 0xFFFF */
57                if (stream->pids[i].pid == pid) {
58                        *pid_channel = stream->pids[i].pidchannel;
59                        *KeySlotHandle = stream->pids[i].KeySlotHandle;
60                        return b_ok;
61                }
62        }
63
64        for (i=0;i<BSETTOP_MAX_PIDS;i++) {
65                if(!(stream->pids[i].pid)){
66                        break;
67                }
68        }
69        if (i == BSETTOP_MAX_PIDS) {
70                goto error;
71        }
72
73        *index = i;
74
75        if (!NEXUS_PidChannel_GetStatus(stream->consumers.decode->video_decode->nPidChannel, &Status)){
76                if(Status.pid == pid) {
77                        *pid_channel = Status.pidChannelIndex ;
78                        *KeySlotHandle = NULL;
79                        stream->pids[i].pid = Status.pid;
80                        stream->pids[i].pidchannel = Status.pidChannelIndex ;
81                        return b_ok;
82                }
83        }
84
85        if (!NEXUS_PidChannel_GetStatus(stream->consumers.decode->audio_decode->nPidChannel, &Status)){
86                if(Status.pid == pid) {
87                        *pid_channel = Status.pidChannelIndex ;
88                        *KeySlotHandle = NULL;
89                        stream->pids[i].pid = Status.pid;
90                        stream->pids[i].pidchannel = Status.pidChannelIndex ;
91                        return b_ok;
92                }
93        }
94
95error:
96        *pid_channel = 0xFFFFFFFF; /* bad number */
97        BDBG_WRN(("Unable to find pid 0x%x on pidparser %p", pid, *pid_channel));
98        return BSETTOP_ERROR(berr_not_available);
99}
100
101bresult bstream_p_reset_pid_info(bstream_t stream, unsigned short pid)
102{
103        int i;
104        for (i=0;i<BSETTOP_MAX_PIDS;i++) {
105                if (stream->pids[i].pid == pid) {
106                        stream->pids[i].pid = 0;
107                        stream->pids[i].pidchannel = 0xFFFFFFFF;
108                        stream->pids[i].KeySlotHandle = NULL; /* Should i do this here? or does the free key slot handle take care of it? */
109                        return 0;
110                }
111        }
112        return BSETTOP_ERROR(b_ok);
113}
114
115/*
116 * There is special handling of stream->storage.mpeg.encryption for the purposes of this function.
117 * It is assumed that the algorithm will be the same for odd and even keys for video vs. audio.
118 *
119 */
120
121bresult bstream_set_encryption(bstream_t stream, const bencryption_params *encryption)
122{
123#if NEXUS_HAS_SECURITY
124        NEXUS_KeySlotHandle KeySlotHandle = NULL;
125        NEXUS_SecurityClearKey ClearKey;
126        NEXUS_SecurityKeySlotSettings Settings;
127        unsigned int pid_channel, index=0;
128        bool call_configure = false;
129        NEXUS_SecurityAlgorithmSettings config_algorithm;
130        NEXUS_Error rc;
131
132        if (encryption->pid == 0x1fff) {
133                bresult rc = b_ok;
134                if (stream->consumers.decode) {
135                        bencryption_params per_pid_encryption;
136                        BKNI_Memcpy(&per_pid_encryption, encryption, sizeof(bencryption_params));
137                        per_pid_encryption.pid = stream->mpeg.video[stream->consumers.decode->video_program].pid;
138                        rc = bstream_set_encryption(stream,&per_pid_encryption);
139                        if (rc == b_ok) {
140                                per_pid_encryption.pid = stream->mpeg.audio[stream->consumers.decode->audio_program].pid;
141                                rc = bstream_set_encryption(stream,&per_pid_encryption);
142                        }
143                } else {
144                        bencryption_params per_pid_encryption;
145                        BKNI_Memcpy(&per_pid_encryption, encryption, sizeof(bencryption_params));
146                        per_pid_encryption.pid = stream->mpeg.video[0].pid;
147                        rc = bstream_set_encryption(stream,&per_pid_encryption);
148                        if (rc == b_ok && stream->mpeg.audio[0].pid) {
149                                per_pid_encryption.pid = stream->mpeg.audio[0].pid;
150                                rc = bstream_set_encryption(stream,&per_pid_encryption);
151                        }
152                        if (rc == b_ok && stream->mpeg.audio[1].pid) {
153                                per_pid_encryption.pid = stream->mpeg.audio[1].pid;
154                                rc = bstream_set_encryption(stream,&per_pid_encryption);
155                        }
156                }
157                return rc;
158        }
159
160        if (encryption->type == bencryption_type_none) {
161                KeySlotHandle = NULL;
162                BDBG_MSG(("bstream_set_encryption: clearing encryption for %02x", encryption->pid));
163
164                if (!bstream_p_lookup_pid_info(stream, encryption->pid, &pid_channel, &KeySlotHandle, &index)) {
165                        if(KeySlotHandle) {
166                                rc = NEXUS_Security_RemovePidChannelFromKeySlot(KeySlotHandle, pid_channel);
167                                if (rc != 0) {
168                                        BDBG_MSG(("NEXUS_Security_RemovePidChannelFromKeySlot: failed "));
169                                        return BSETTOP_ERROR(berr_invalid_parameter);
170                                }
171                                NEXUS_Security_FreeKeySlot(KeySlotHandle);
172                                bstream_p_reset_pid_info(stream, encryption->pid);
173                        }
174                }
175                /* using stream->mpeg.encryption to store configuration information */
176                stream->mpeg.encryption.type = bencryption_type_none;
177                stream->mpeg.encryption.odd = false;
178                stream->mpeg.encryption.even = false;
179                stream->ca_state.video_odd_key_config = 0;
180                stream->ca_state.video_even_key_config = 0;
181                stream->ca_state.audio_odd_key_config = 0;
182                stream->ca_state.audio_even_key_config = 0;
183        }
184        else
185        {
186                if (encryption->key_ladder) {
187                        BDBG_ERR(("bstream_set_encryption: keyladder is not supported"));
188                        return BSETTOP_ERROR(berr_invalid_parameter);
189                }
190
191                if (bstream_p_lookup_pid_info(stream, encryption->pid, &pid_channel, &KeySlotHandle, &index)) {
192                        BDBG_ERR(("bstream_set_encryption: failed to look up pid channel for pid: %02x",encryption->pid));
193                        return BSETTOP_ERROR(berr_invalid_parameter);
194                }
195
196                if (!KeySlotHandle) {
197                        NEXUS_Security_GetDefaultKeySlotSettings(&Settings);
198                        Settings.keySlotEngine = NEXUS_SecurityEngine_eCa;
199                        BDBG_MSG(("bstream_set_encryption: Allocating new key slot (type: %d)"));
200
201                        KeySlotHandle = NEXUS_Security_AllocateKeySlot(&Settings);
202                        stream->pids[index].KeySlotHandle = KeySlotHandle;
203                }
204
205                /* BKNI_Memset(&config_algorithm, 0, sizeof(NEXUS_SecurityAlgorithmSettings)); */
206                NEXUS_Security_GetDefaultAlgorithmSettings(&config_algorithm);
207
208                switch (encryption->residue) {
209                case bencryption_residue_none:
210                        BDBG_MSG(("bstream_set_encryption: configuring no residue"));
211                        config_algorithm.terminationMode = NEXUS_SecurityTerminationMode_eClear;
212                        break;
213                case bencryption_residue_block_term:
214                        BDBG_MSG(("bstream_set_encryption: configuring block termination mode"));
215                        config_algorithm.terminationMode = NEXUS_SecurityTerminationMode_eBlock;
216                        break;
217                case bencryption_residue_cipher_text:
218                        BDBG_MSG(("bstream_set_encryption: configuring cipher text stealing"));
219                        config_algorithm.terminationMode = NEXUS_SecurityTerminationMode_eCipherStealing;
220                        break;
221                }
222
223                switch (encryption->type) {
224                case bencryption_type_dvb:
225                        BDBG_MSG(("bstream_set_encryption: configuring DVB for %s",stream->mpeg.mpeg_type == bstream_mpeg_type_pes ? "PES" : "TS"));
226                        config_algorithm.algorithm = NEXUS_SecurityAlgorithm_eDvb;
227                        config_algorithm.dvbScramLevel = stream->mpeg.mpeg_type == bstream_mpeg_type_pes ? NEXUS_SecurityDvbScrambleLevel_ePes : NEXUS_SecurityDvbScrambleLevel_eTs;
228                        ClearKey.keySize = 8; /* 8 bytes (64 bits) */
229                        break;
230                case bencryption_type_aes:
231                        BDBG_MSG(("bstream_set_encryption: configuring AES for %s",encryption->blockmode == bcrypto_blockmode_cbc ? "CBC" : "ECB"));
232                        config_algorithm.algorithm = NEXUS_SecurityAlgorithm_eAes;
233                        config_algorithm.algorithmVar = encryption->blockmode == bcrypto_blockmode_cbc ? NEXUS_SecurityAlgorithmVariant_eCbc : NEXUS_SecurityAlgorithmVariant_eEcb;
234                        ClearKey.keySize = 16; /* 16 bytes (128 bits) */
235                        break;
236                case bencryption_type_des:
237                        BDBG_MSG(("bstream_set_encryption: configuring DES for %s",encryption->blockmode == bcrypto_blockmode_cbc ? "CBC" : "ECB"));
238                        config_algorithm.algorithm = NEXUS_SecurityAlgorithm_eDes;
239                        config_algorithm.algorithmVar = encryption->blockmode == bcrypto_blockmode_cbc ? NEXUS_SecurityAlgorithmVariant_eCbc : NEXUS_SecurityAlgorithmVariant_eEcb;
240                        ClearKey.keySize = 8; /* 8 bytes (64 bits) */
241                        break;
242                case bencryption_type_3des:
243                        BDBG_MSG(("bstream_set_encryption: configuring 3DES for %s",encryption->blockmode == bcrypto_blockmode_cbc ? "CBC" : "ECB"));
244                        config_algorithm.algorithm = NEXUS_SecurityAlgorithm_e3DesAba;
245                        config_algorithm.algorithmVar = encryption->blockmode == bcrypto_blockmode_cbc ? NEXUS_SecurityAlgorithmVariant_eCbc : NEXUS_SecurityAlgorithmVariant_eEcb;
246                        ClearKey.keySize = 16; /* 16 bytes (128 bits) */
247                        break;
248        case bencryption_type_multi2:
249            BDBG_MSG(("bstream_set_encryption: configuring multi2 for %s",encryption->blockmode == bcrypto_blockmode_cbc ? "CBC" : "ECB"));
250            config_algorithm.algorithm = NEXUS_SecurityAlgorithm_eMulti2;
251            config_algorithm.algorithmVar = encryption->blockmode == bcrypto_blockmode_cbc ? NEXUS_SecurityAlgorithmVariant_eCbc : NEXUS_SecurityAlgorithmVariant_eEcb;
252            config_algorithm.multi2KeySelect = encryption->m2_key_select;
253            ClearKey.keySize = 8; /* 8 bytes (64 bits) */
254            break;
255                default:
256                        BDBG_ERR(("bstream_set_encryption: unsupported CA algorithm"));
257                        return BSETTOP_ERROR(berr_invalid_parameter);
258                }
259
260                if (encryption->use_cps) {
261                        call_configure = true;
262                } else {
263                        if (stream->consumers.decode) {
264                                if (encryption->pid == stream->mpeg.video[stream->consumers.decode->video_program].pid) {
265                                        if (encryption->odd && (encryption->pid != stream->ca_state.video_odd_key_config) ) {
266                                                stream->ca_state.video_odd_key_config = encryption->pid;
267                                                stream->ca_state.video_even_key_config = encryption->pid;
268                                                call_configure = true;
269                                        }
270                                        if (encryption->even && (encryption->pid != stream->ca_state.video_odd_key_config) ) {
271                                                stream->ca_state.video_odd_key_config = encryption->pid;
272                                                stream->ca_state.video_even_key_config = encryption->pid;
273                                                call_configure = true;
274                                        }
275                                }
276                                if (encryption->pid == stream->mpeg.audio[stream->consumers.decode->audio_program].pid) {
277                                        if (encryption->odd && (encryption->pid != stream->ca_state.audio_odd_key_config) ) {
278                                                stream->ca_state.audio_odd_key_config = encryption->pid;
279                                                stream->ca_state.audio_even_key_config = encryption->pid;
280                                                call_configure = true;
281                                        }
282                                        if (encryption->even && (encryption->pid != stream->ca_state.audio_odd_key_config) ) {
283                                                stream->ca_state.audio_odd_key_config = encryption->pid;
284                                                stream->ca_state.audio_even_key_config = encryption->pid;
285                                                call_configure = true;
286                                        }
287                                }
288                        } else {
289                                if (encryption->pid == stream->mpeg.video[0].pid) {
290                                        if (encryption->odd && (encryption->pid != stream->ca_state.video_odd_key_config)) {
291                                                stream->ca_state.video_odd_key_config = encryption->pid;
292                                                call_configure = true;
293                                        }
294                                        if (encryption->even && (encryption->pid != stream->ca_state.video_even_key_config)) {
295                                                stream->ca_state.video_even_key_config = encryption->pid;
296                                                call_configure = true;
297                                        }
298                                }
299                                if (encryption->pid == stream->mpeg.audio[0].pid ||
300                                        encryption->pid == stream->mpeg.audio[1].pid ) {
301                                        if (encryption->odd && (encryption->pid != stream->ca_state.audio_odd_key_config)) {
302                                                stream->ca_state.audio_odd_key_config = encryption->pid;
303                                                call_configure = true;
304                                        }
305                                        if (encryption->even && (encryption->pid != stream->ca_state.audio_even_key_config)) {
306                                                stream->ca_state.audio_even_key_config = encryption->pid;
307                                                call_configure = true;
308                                        }
309                                }
310                        }
311                }
312
313                if (call_configure) {
314
315                        rc = NEXUS_Security_ConfigAlgorithm( KeySlotHandle, &config_algorithm);
316                        if (rc != 0) {
317                                BDBG_MSG(("bstream_set_encryption: failed to configure algorithm"));
318                                return BSETTOP_ERROR(berr_invalid_parameter);
319                        }
320                        stream->mpeg.encryption.type = encryption->type;
321
322                        rc = NEXUS_Security_AddPidChannelToKeySlot(KeySlotHandle, pid_channel);
323                        if (rc != 0) {
324                                BDBG_ERR(("bstream_set_encryption: failed to configure pid key pointer table"));
325                                return BSETTOP_ERROR(berr_invalid_parameter);
326                        }
327                }
328
329                if (encryption->key_ladder) {
330                        BDBG_ERR(("bstream_set_encryption: Keyladder is not supported"));
331                        return BSETTOP_ERROR(berr_invalid_parameter);
332                }
333                else {
334            if (encryption->type == bencryption_type_multi2) {
335                NEXUS_SecurityMulti2Settings config_multi2;
336
337                NEXUS_Security_GetDefaultMulti2Settings(&config_multi2);
338                config_multi2.multi2KeySelect = encryption->m2_key_select;
339                config_multi2.multi2Rounds = encryption->m2_round;
340                memcpy(config_multi2.multi2SysKey, encryption->m2_sys_key, 32);
341
342                if ( NEXUS_Security_ConfigMulti2(KeySlotHandle, &config_multi2) != 0 )
343                {
344                    BDBG_ERR(("bstream_set_encryption: multi2 configuration failed"));
345                    return BSETTOP_ERROR(berr_external_error);
346                }
347            }
348
349                        /* Route a clear key */
350                        BKNI_Memcpy(ClearKey.keyData,encryption->key,encryption->key_length/8);
351                        ClearKey.keyEntryType = encryption->odd ? NEXUS_SecurityKeyType_eOdd : NEXUS_SecurityKeyType_eEven;
352                        BDBG_MSG(("NEXUS_Security_LoadClearKey called if odd key is set"));
353
354                        rc = NEXUS_Security_LoadClearKey( KeySlotHandle, &ClearKey);
355                        if (rc != 0) {
356                                BDBG_MSG(("bstream_set_encryption: failed to route user key"));
357                                return BSETTOP_ERROR(berr_invalid_parameter);
358                        }
359                        if (encryption->odd && encryption->even) {
360                                ClearKey.keyEntryType = NEXUS_SecurityKeyType_eEven;
361                                BDBG_MSG(("NEXUS_Security_LoadClearKey called if odd n even key are set"));
362
363                                rc = NEXUS_Security_LoadClearKey( KeySlotHandle, &ClearKey);
364                                if (rc != 0) {
365                                        BDBG_MSG(("bstream_set_encryption: failed to route user key"));
366                                        return BSETTOP_ERROR(berr_invalid_parameter);
367                                }
368                        }
369                        if (encryption->blockmode == bcrypto_blockmode_cbc) {
370                                ClearKey.keySize = 16; /* 16 bytes */
371                                BKNI_Memcpy(ClearKey.keyData,encryption->iv,16);
372                                ClearKey.keyEntryType = NEXUS_SecurityKeyType_eIv;
373                                BDBG_MSG(("NEXUS_Security_LoadClearKey called for IV"));
374
375                                rc = NEXUS_Security_LoadClearKey( KeySlotHandle, &ClearKey);
376                                if (rc != 0) {
377                                        BDBG_MSG(("bstream_set_encryption: failed to load IV"));
378                                        return BSETTOP_ERROR(berr_invalid_parameter);
379                                }
380                        }
381                }
382        }
383#else
384BSTD_UNUSED(stream);
385BSTD_UNUSED(encryption);
386#endif /* NEXUS_HAS_SECURITY */
387        return b_ok;
388}
389
Note: See TracBrowser for help on using the repository browser.