Changeset 8377


Ignore:
Timestamp:
02/19/13 14:25:10 (9 years ago)
Author:
gf
Message:

cryptoworks/viaccess: Run EMM reassembly before writing EMM in the card.

Before this patch EMM reassembly was only run by the dvbapi client.

This means that any other client (via newcamd, cs378x, cccam) was
expected to perform its own EMM reassembly otherwise the card
was unable to write the EMMs that needed preprocessing (reassemblation).

This commit moves EMM reassembly where it belongs - just before the
EMM is written in the card. That simplifies client logic (no more
knowledge of EMM structure and types) and allows cards to be updated
via any network protocol as long as the client is not trying to be
smart and just sends us all EMM packets.

The changes were tested with SRG Swiss Viacess card and Digiturk
Cryptoworks card. In the both cards shared EMMs were written OK
while receiving them via cs378x protocol and tsdecrypt as client.

If a client sends already reassembled EMMs it also works.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/globals.h

    r8370 r8377  
    708708    int32_t     (*card_info)(struct s_reader *);
    709709    int32_t     (*do_ecm)(struct s_reader *, const struct ecm_request_t *, struct s_ecm_answer *);
     710    bool        (*do_emm_reassembly)(struct s_reader *, struct emm_packet_t *); // Returns 1/true if the EMM is ready to be written in the card
    710711    int32_t     (*do_emm)(struct s_reader *, struct emm_packet_t *);
    711712    void            (*post_process)(struct s_reader *);
     
    11721173    int8_t          card_status;
    11731174    int8_t          deprecated;                     //if 0 ATR obeyed, if 1 default speed (9600) is chosen; for devices that cannot switch baudrate
     1175    int32_t         reassemble_emm_len;
     1176    uint8_t         reassemble_emm[512];
    11741177    struct s_module ph;
    11751178    struct s_cardreader crdr;
  • trunk/module-dvbapi.c

    r8376 r8377  
    532532
    533533    dvbapi_set_filter(demux_id, selected_api, pid, caid, 0, filter, filter+16, timeout, pidindex, count, type, 0);
    534 }
    535 
    536 void dvbapi_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len)
    537 {
    538     int32_t w=0, c=-1, j=0;
    539     while(1) {
    540         int32_t n=0x100;
    541         for(j=0; j<len;) {
    542             int32_t l=src[j+1]+2;
    543                 if(src[j]==c) {
    544                     if(w+l>len) {
    545                         cs_debug_mask(D_DVBAPI, "sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!");
    546                         memset(dest,0,len); // zero out everything
    547                         return;
    548                     }
    549                     memcpy(&dest[w],&src[j],l);
    550                 w+=l;
    551             } else if(src[j]>c && src[j]<n)
    552                 n=src[j];
    553             j+=l;
    554         }
    555         if(n==0x100) break;
    556         c=n;
    557     }
    558534}
    559535
     
    10521028}
    10531029
    1054 #ifdef READER_VIACCESS
    1055 extern int32_t viaccess_reassemble_emm(uchar *buffer, uint32_t *len);
    1056 #endif
    1057 #ifdef READER_CRYPTOWORKS
    1058 extern int32_t cryptoworks_reassemble_emm(uchar *buffer, uint32_t *len);
    1059 #endif
    1060 
    10611030void dvbapi_process_emm (int32_t demux_index, int32_t filter_num, unsigned char *buffer, uint32_t len) {
    10621031    EMM_PACKET epg;
     
    10691038    uint32_t provider = filter->provid;
    10701039    uint16_t caid = filter->caid;
    1071 
    1072     switch (caid >> 8) {
    1073         case 0x05:
    1074 #ifdef READER_VIACCESS
    1075             if (!viaccess_reassemble_emm(buffer, &len))
    1076 #endif
    1077                 return;
    1078             break;
    1079             case 0x0d:
    1080 #ifdef READER_CRYPTOWORKS
    1081             if (!cryptoworks_reassemble_emm(buffer, &len))
    1082 #endif
    1083                 return;
    1084             break;
    1085     }
    1086 
    10871040
    10881041    cs_debug_mask(D_DVBAPI, "emm from fd %d", demux[demux_index].demux_fd[filter_num].fd); //emm shown with -d64
  • trunk/oscam-emm.c

    r8294 r8377  
    319319        }
    320320
     321        if (aureader->csystem.do_emm_reassembly && !aureader->csystem.do_emm_reassembly(aureader, ep))
     322            return;
     323
    321324        rdr_debug_mask_sensitive(aureader, D_EMM, "emmtype %s. Reader serial {%s}.", typtext[ep->type],
    322325            cs_hexdump(0, aureader->hexserial, 8, tmp, sizeof(tmp)));
     
    519522    free(eptmp);
    520523}
     524
     525void emm_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len)
     526{
     527    int32_t w = 0, c = -1, j = 0;
     528    while(1) {
     529        int32_t n = 256;
     530        for (j = 0; j < len; ) {
     531            int32_t l = src[j + 1] + 2;
     532            if (src[j] == c) {
     533                if (w + l > len) {
     534                    cs_debug_mask(D_EMM, "sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!");
     535                    memset(dest, 0, len); // zero out everything
     536                    return;
     537                }
     538                memcpy(&dest[w],&src[j],l);
     539                w += l;
     540            } else if (src[j] > c && src[j] < n) {
     541                n = src[j];
     542            }
     543            j += l;
     544        }
     545        if (n >= 256)
     546            break;
     547        c = n;
     548    }
     549}
  • trunk/oscam-emm.h

    r8241 r8377  
    66int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep);
    77void do_emm_from_file(struct s_reader * reader);
     8void emm_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len);
    89
    910#endif
  • trunk/reader-common.c

    r8280 r8377  
    3737  reader->acs=0;
    3838  reader->nprov=0;
     39  reader->reassemble_emm_len=0;
     40  memset(reader->reassemble_emm, 0, sizeof(reader->reassemble_emm));
    3941}
    4042
  • trunk/reader-cryptoworks.c

    r8293 r8377  
    22#ifdef READER_CRYPTOWORKS
    33#include "oscam-config.h"
     4#include "oscam-emm.h"
    45#include "reader-common.h"
    56
     
    454455                ep->type = SHARED;
    455456                i2b_buf(4, cryptoworks_get_emm_provid(ep->emm+8, ep->emmlen-8), ep->provid);
    456                 return 0;
     457                // We need those packets to pass otherwise we would never
     458                // be able to complete EMM reassembly
     459                return 1;
    457460            }
    458461            break;
     
    702705}
    703706
    704 #ifdef HAVE_DVBAPI
    705 void dvbapi_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len);
    706 
    707 int32_t cryptoworks_reassemble_emm(uchar *buffer, uint32_t *len) {
    708     static uchar emm_global[512];       // function only called from dvbapi thread, no need to be threadsafe
    709     static int32_t emm_global_len = 0;
    710     int32_t emm_len = 0;
     707static bool cryptoworks_reassemble_emm(struct s_reader *reader, EMM_PACKET *ep)
     708{
     709    uchar *buffer = ep->emm;
     710    int16_t *len = &ep->emmlen;
     711    int16_t emm_len = 0;
    711712
    712713    // Cryptoworks
     
    726727        case 0x84: // emm-sh
    727728            cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (EMM-SH): %s" , cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
    728             if (!memcmp(emm_global, buffer, *len)) return 0;
    729             memcpy(emm_global, buffer, *len);
    730             emm_global_len=*len;
    731             return 0;
     729            if (!memcmp(reader->reassemble_emm, buffer, *len)) return 0;
     730            memcpy(reader->reassemble_emm, buffer, *len);
     731            reader->reassemble_emm_len=*len;
     732            // If we return 0 (skip packet) and someone send us already
     733            // reassembled packet we would miss it. Thats why we return 1 (ok)
     734            // and "suffer" couple of wrongly written packets in the card.
     735            return 1;
    732736
    733737        case 0x86: // emm-sb
    734738            cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (EMM-SB): %s" , cs_hexdump(0, buffer, *len, dumpbuf, sizeof(dumpbuf)));
    735             if (!emm_global_len) return 0;
     739            if (!reader->reassemble_emm_len) return 0;
    736740
    737741            // we keep the first 12 bytes of the 0x84 emm (EMM-SH)
     
    745749            //
    746750
    747             emm_len=*len-5 + emm_global_len-12;
     751            emm_len=*len-5 + reader->reassemble_emm_len-12;
    748752            unsigned char *tmp, *assembled;
    749753            if (!cs_malloc(&tmp, emm_len))
     
    760764            }
    761765            memcpy(tmp,&buffer[5], *len-5);
    762             memcpy(tmp+*len-5,&emm_global[12],emm_global_len-12);
    763             memcpy(assembled_EMM,emm_global,12);
    764             dvbapi_sort_nanos(assembled_EMM+12,tmp,emm_len);
     766            memcpy(tmp+*len-5,&reader->reassemble_emm[12],reader->reassemble_emm_len-12);
     767            memcpy(assembled_EMM,reader->reassemble_emm,12);
     768            emm_sort_nanos(assembled_EMM+12,tmp,emm_len);
    765769
    766770            assembled_EMM[1]=((emm_len+9)>>8) | 0x70;
     
    774778            free(assembled_EMM);
    775779
    776             emm_global_len=0;
     780            reader->reassemble_emm_len = 0;
    777781
    778782            cs_debug_mask(D_DVBAPI, "[cryptoworks] shared emm (assembled): %s", cs_hexdump(0, buffer, emm_len+12, dumpbuf, sizeof(dumpbuf)));
     
    791795    return 1;
    792796}
    793 #endif
    794797
    795798void reader_cryptoworks(struct s_cardsystem *ph)
    796799{
     800    ph->do_emm_reassembly=cryptoworks_reassemble_emm;
    797801    ph->do_emm=cryptoworks_do_emm;
    798802    ph->do_ecm=cryptoworks_do_ecm;
  • trunk/reader-viaccess.c

    r8376 r8377  
    33#include "oscam-aes.h"
    44#include "oscam-time.h"
     5#include "oscam-emm.h"
    56#include "reader-common.h"
    67
     
    611612    ep->type=SHARED;
    612613    rdr_debug_mask(rdr, D_EMM, "SHARED (part)");
    613     return 0;
     614    // We need those packets to pass otherwise we would never
     615    // be able to complete EMM reassembly
     616    return 1;
    614617
    615618case 0x8E:
     
    641644    filter[1]=0;
    642645
    643     filter[idx++]=EMM_GLOBAL;
     646    filter[idx++]=EMM_SHARED;
     647    filter[idx++]=0;
     648    filter[idx+0]     = 0x8C;
     649    filter[idx+0+16]  = 0xFF;
     650    filter[1]++;
     651    idx += 32;
     652
     653    filter[idx++]=EMM_SHARED;
    644654    filter[idx++]=0;
    645655    filter[idx+0]     = 0x8D;
    646     filter[idx+0+16]  = 0xFE;
    647     //filter[idx+6]     = 0xA0; // FIXME: dummy, flood client with EMM's
    648     //filter[idx+6+16]  = 0xF0;
     656    filter[idx+0+16]  = 0xFF;
    649657    filter[1]++;
    650658    idx += 32;
     
    985993}
    986994
    987 #ifdef HAVE_DVBAPI
    988 void dvbapi_sort_nanos(unsigned char *dest, const unsigned char *src, int32_t len);
    989 
    990 int32_t viaccess_reassemble_emm(uchar *buffer, uint32_t *len) {
    991     static uchar emm_global[512];
    992     static int32_t emm_global_len = 0;
    993 
     995static bool viaccess_reassemble_emm(struct s_reader *reader, EMM_PACKET *ep)
     996{
     997    uint8_t *buffer = ep->emm;
     998    int16_t *len = &ep->emmlen;
    994999    int32_t pos=0, i;
    995     uint32_t k;
     1000    int16_t k;
    9961001
    9971002    // Viaccess
     
    10021007        case 0x8d:
    10031008            // emm-s part 1
    1004             if (!memcmp(emm_global, buffer, *len))
     1009            if (!memcmp(reader->reassemble_emm, buffer, *len))
    10051010                return 0;
    10061011
    10071012            // copy first part of the emm-s
    1008             memcpy(emm_global, buffer, *len);
    1009             emm_global_len=*len;
     1013            memcpy(reader->reassemble_emm, buffer, *len);
     1014            reader->reassemble_emm_len=*len;
    10101015            //cs_ddump_mask(D_READER, buffer, len, "viaccess global emm:");
    10111016            return 0;
     
    10131018        case 0x8e:
    10141019            // emm-s part 2
    1015             if (!emm_global_len) return 0;
     1020            if (!reader->reassemble_emm_len) return 0;
    10161021
    10171022            //extract nanos from emm-gh and emm-s
     
    10201025            cs_debug_mask(D_DVBAPI, "[viaccess] %s: start extracting nanos", __func__);
    10211026            //extract from emm-gh
    1022             for (i=3; i<emm_global_len; i+=emm_global[i+1]+2) {
     1027            for (i=3; i<reader->reassemble_emm_len; i+=reader->reassemble_emm[i+1]+2) {
    10231028                //copy nano (length determined by i+1)
    1024                 memcpy(emmbuf+pos, emm_global+i, emm_global[i+1]+2);
    1025                 pos+=emm_global[i+1]+2;
     1029                memcpy(emmbuf+pos, reader->reassemble_emm+i, reader->reassemble_emm[i+1]+2);
     1030                pos+=reader->reassemble_emm[i+1]+2;
    10261031            }
    10271032
     
    10471052            cs_ddump_mask(D_DVBAPI, buffer, *len, "[viaccess] %s: %s emm-s", __func__, (buffer[2]==0x2c) ? "fixed" : "variable");
    10481053
    1049             dvbapi_sort_nanos(buffer+7, emmbuf, pos);
     1054            emm_sort_nanos(buffer+7, emmbuf, pos);
    10501055            pos+=7;
    10511056
     
    10531058            buffer[2]=pos-3;
    10541059
    1055             cs_ddump_mask(D_DVBAPI, emm_global, emm_global_len, "[viaccess] %s: emm-gh", __func__);
     1060            cs_ddump_mask(D_DVBAPI, reader->reassemble_emm, reader->reassemble_emm_len, "[viaccess] %s: emm-gh", __func__);
    10561061            cs_ddump_mask(D_DVBAPI, buffer, pos, "[viaccess] %s: assembled emm", __func__);
    10571062
     
    10611066    return 1;
    10621067}
    1063 #endif
    10641068
    10651069void reader_viaccess(struct s_cardsystem *ph)
    10661070{
     1071    ph->do_emm_reassembly=viaccess_reassemble_emm;
    10671072    ph->do_emm=viaccess_do_emm;
    10681073    ph->do_ecm=viaccess_do_ecm;
Note: See TracChangeset for help on using the changeset viewer.