
    hp                        d dl Z d dlZd dlmZ d dlmZmZ d dlmZ d dl	m
Z
mZmZmZ d dl	mZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ  ej        e          Ze                    ej                   dede dedefdZ!d'dedefdZ"dedefdZ# G d d          Z$dZ%dZ&dZ' G d dee j(                  Z) G d de)          Z*d dlm+Z+ d dl,m-Z- d(ded eded!ee          def
d"Z. G d# d$          Z/ G d% d&e)          Z0dS ))    N)Optional)DES3DES)strxor)StructInt8ubInt16ubConst)Bytes)b2h)bertlv_parse_lenbertlv_encode_len)parse_command_apdu)SecureChannelconstantcounterbase_keyreturnc                    t          |           dk    sJ |dk    r|dk    sJ t          |          dk    sJ | |                    dd          z   dz   }t          j        |t          j        d          }|                    |          S )N   r        bigs                          )lento_bytesr   newr   MODE_CBCencrypt)r   r   r   derivation_dataciphers        G/home/jenkins/workspace/simtester-sanitize/pySim/global_platform/scp.pyscp02_key_derivationr#   "   s    x==Aa<<Gu,,,,x==B!1!1!U!;!;;lJOXhk::F>>/***       sc                 H    |dz
  t          |           |z  z
  }| dz   d|z  z   S )uH    Pad bytestring s: add '' and ' '* so the result to be multiple of BS.          )r   )r&   BSls      r"   pad80r-   ,   s-    
1s1vv{Aw;q  r$   paddedc                 \    |                      d          }|d         dk    sJ |dd         S )z7Remove the customary 80 00 00 ... padding used for AES.r*      N)rstrip)r.   strippeds     r"   unpad80r4   2   s8     }}U##HB<4CRC=r$   c                   j    e Zd ZdZdZdZdZdZdZdde	d	e
d
e	fdZde	d
e	fdZddeddfdZd
efdZdS )Scp02SessionKeysz,A single set of GlobalPlatform session keys.s   s   s   s   r%   Fdata	reset_icvr   c                    t          j        | j        dd         t           j                  }t          j        | j        dd         t           j                  }t	          |d          }t          |          dz  }|rdn| j        }|}t          |          D ]C}	|                    t          |t          |d|	z  d|	dz   z                                         }D|                    |          }|                    |          }t                              dt          |          t          |          t          |                     | j        r | j                            |          | _        n|| _        |S )zGPad and calculate MAC according to B.1.2.2 - Single DES plus final 3DESNr%   r   r(   zmac_1des(%s,icv=%s) -> %s)r   r   c_macMODE_ECBr-   r   icvranger   r   bytesdecryptloggerdebugr   des_icv_enc)
selfr7   r8   edpadded_dataqr<   his
             r"   calc_mac_1deszScp02SessionKeys.calc_mac_1desB   s;   GDJrrNCL11GDJqrrNCL11D!nn!&4kkDHq 	F 	FA		&E+ac!QqS'k*B$C$CDDEEAAIIaLLIIaLL0#d))SXXs1vvNNN 	'//22DHHDHr$   c                    t          j        | j        t          j                  }t          |d          }t          |          dz  }d}t          |          D ]C}|                    t          |t          |d|z  d|dz   z                                         }Dt                              dt          |          t          |                     |S )Nr%   r   r(   zmac_3des(%s) -> %s)r   r   encr   r;   r-   r   r=   r   r   r>   r@   rA   r   )rC   r7   rD   rF   rG   rH   rI   s          r"   calc_mac_3deszScp02SessionKeys.calc_mac_3desU   s    HTXs|,,D!nn!q 	F 	FA		&E+ac!QqS'k*B$C$CDDEEAA)3t99c!ff===r$   Tr   	card_keysGpCardKeysetc                    d | _         || _        || _        t          | j        | j        |j                  | _        t          | j        | j        |j                  | _        t          | j	        | j        |j
                  | _
        t          | j        | j        |j                  | _        |r,t          j        | j        d d         t          j                  nd | _        d S Nr%   )r<   r   rN   r#   DERIV_CONST_CMACmacr:   DERIV_CONST_RMACr_macDERIV_CONST_ENCrL   DERIV_CONST_DENCdekdata_encr   r   r;   rB   )rC   r   rN   icv_encrypts       r"   __init__zScp02SessionKeys.__init___   s    ")$*?y}]]
)$*?y}]]
'(<dlIMZZ,T-BDLR[R_``DOY374:bqb>3<@@@UYr$   c           
          d| j         j        | j        | j        rt	          | j                  ndt	          | j                  t	          | j                  t	          | j                  t	          | j                  fz  S )Nz8%s(CTR=%u, ICV=%s, ENC=%s, D-ENC=%s, MAC-C=%s, MAC-R=%s)None)		__class____name__r   r<   r   rL   rY   r:   rU   rC   s    r"   __str__zScp02SessionKeys.__str__i   se    I'7\s48}}}V\DHs4=113tz??C
OOMU U 	Ur$   NFT)r_   
__module____qualname____doc__rR   rT   rV   rW   	blocksizer>   boolrJ   rM   intr[   strra    r$   r"   r6   r6   :   s        66""!O"I % D U    &% E    Z Z Z Z Z Z ZU U U U U U Ur$   r6   P         c                      e Zd ZdZd%dddefdZedefd            Zedefd	            Z	edefd
            Z
edefd            ZdefdZd&dededefdZdedefdZej        dedefd            Zej        dee         defd            Zej        defd            Zej        d'dedefd            ZdedefdZdedefdZej        d edefd!            Zej        d"edefd#            Zd$S )(SCPzWAbstract base class containing some common interface + functionality for SCP protocols.r   rN   rO   lchan_nrc                    j         dk    rnt          | d          rfj         t          | j        d         | j        d         dz             vr5t	          d| j        j        | j        d         | j        d         fz            nSt          | d          rCt          fd| j        D                       r#t	          | j        j        d| j                  || _	        | _
        d | _        d| _        d| _        d S )	Nr   	kvn_ranger(   z7%s cannot be used with KVN outside range 0x%02x..0x%02x
kvn_rangesc                 \    g | ](}j         t          |d          |d         dz             v)S )r   r(   )kvnr=   ).0xrN   s     r"   
<listcomp>z SCP.__init__.<locals>.<listcomp>   s6    VVV	qtQqT!V)<)<<VVVr$   z2 cannot be used with KVN outside permitted ranges F)rv   hasattrr=   rs   
ValueErrorr^   r_   allrt   rq   rN   skmac_on_unmodifiedsecurity_level)rC   rN   rq   s    ` r"   r[   zSCP.__init__t   s/   : =A T;'' 	M=E$.*;T^A=Nq=P$Q$QQQ !Z"&."94>!;Ldn]^N_!`"a b b b R T<(( 	MVVVVdoVVVWW M "&."9"9"94??"L M M M !"!&"r$   r   c                     | j         dz  S )zShould we perform C-MAC?r(   r   r`   s    r"   do_cmaczSCP.do_cmac        "T))r$   c                     | j         dz  S )zShould we perform R-MAC?r   r   r`   s    r"   do_rmaczSCP.do_rmac   r   r$   c                     | j         dz  S )zShould we perform C-ENC?r   r   r`   s    r"   do_cenczSCP.do_cenc   r   r$   c                     | j         dz  S )zShould we perform R-ENC?    r   r`   s    r"   do_renczSCP.do_renc   r   r$   c                 .    d| j         j        | j        fz  S )Nz%s[%02x])r^   r_   r   r`   s    r"   ra   zSCP.__str__   s    T^4d6IJJJr$   FTsmb8c                 :    |rdnd}|r
|t           z  }|| j        z   S )Nr1   r   )CLA_SMrq   )rC   r   r   rets       r"   _clazSCP._cla   s.    "ddd 	,CT]""r$   apduc                 >    |d         dz  r | j         |g|R i |S |S )Nr   r1   )_wrap_cmd_apdurC   r   argskwargss       r"   wrap_cmd_apduzSCP.wrap_cmd_apdu   s<     7T> 	>&4&t=d===f===r$   c                     dS )z6Method implementation to be provided by derived class.Nrk   r   s       r"   r   zSCP._wrap_cmd_apdu   s	     	r$   host_challengec                     d S Nrk   rC   r   s     r"   gen_init_update_apduzSCP.gen_init_update_apdu       r$   resp_binc                     d S r   rk   )rC   r   s     r"   parse_init_update_respzSCP.parse_init_update_resp   r   r$   r(   r   c                     d S r   rk   )rC   r   s     r"   gen_ext_auth_apduzSCP.gen_ext_auth_apdu   r   r$   keyc                     t          |          | j        j        z  }|r8t          t          |                    |                     |d|z  z             z   S |                     |          S )zEncrypt a key with the DEK.r*   )r   r}   rg   r   dek_encrypt)rC   r   num_pads      r"   encrypt_keyzSCP.encrypt_key   se    c((TW.. 	Y$SXX..1A1A#PWBW1X1XXX$$$r$   encrypted_keyc                     t          |          | j        j        z  r1|                     |          }t	          |          \  }}|d|         S |                     |          S )zDecrypt a key with the DEK.N)r   r}   rg   dek_decryptr   )rC   r   	decryptedkey_len	remainders        r"   decrypt_keyzSCP.decrypt_key   sh    } 11 	3 ((77I!1)!<!<GYXgX&& ##M222r$   	plaintextc                     d S r   rk   )rC   r   s     r"   r   zSCP.dek_encrypt   r   r$   
ciphertextc                     d S r   rk   )rC   r   s     r"   r   zSCP.dek_decrypt   r   r$   N)r   )FTr(   )r_   rd   re   rf   ri   r[   propertyrh   r   r   r   r   rj   ra   r   r>   r   abcabstractmethodr   r   r   r   r   r   r   r   r   rk   r$   r"   rp   rp   r   s       aa/# /#. /#C /# /# /# /#b * * * * X* * * * * X* * * * * X* * * * * X*K K K K K# #t # # # # # #% U     	5 e     	8E? u     	u     	  u    %u % % % % %3 3% 3 3 3 3* 	E e     	U u      r$   rp   c                   B    e Zd ZdZ ed ed          z  dez   ed          dez  d ed          z  d	 ed
          z            Z	ddgddgddggZ
 fdZdedefdZdedefdZdedefdZd"dedefdZdefdZd#dedefdZdedefdZded edefd!Z xZS )$SCP02z@An instance of the GlobalPlatform SCP02 secure channel protocol.key_div_data
   key_ver   seq_countercard_challenge   card_cryptogramr%   r(   r   /   p   c                 H    d| _          t                      j        |i | d S rQ   )overheadsuperr[   rC   r   r   r^   s      r"   r[   zSCP02.__init__  s,    $)&)))))r$   r   r   c                     t          j        | j        j        d d         t           j                  }|                    |          S rQ   )r   r   rN   rX   r;   r   rC   r   r!   s      r"   r   zSCP02.dek_encrypt  s5    +BQB/>>~~i(((r$   r   c                     t          j        | j        j        d d         t           j                  }|                    |          S rQ   )r   r   rN   rX   r;   r?   rC   r   r!   s      r"   r   zSCP02.dek_decrypt  s5    +BQB/>>~~j)))r$   r   c                    t                               dt          |          t          |                     | j                            | j        j                            dd          |z   |z             | _        | j                            | j        | j        j                            dd          z   |z             | _	        t                               dt          | j                  t          | j	                             d S )N&host_challenge(%s), card_challenge(%s)r   r   (host_cryptogram(%s), card_cryptogram(%s))
r@   rA   r   r}   rM   r   r   host_cryptogramr   r   )rC   r   r   s      r"   _compute_cryptogramszSCP02._compute_cryptograms  s    =s>?R?RTWXfTgTghhh#w44TW_5M5MaQV5W5WZh5hky5yzz#w44T5H47?KcKcdeglKmKm5mp~5~?TEYAZAZ\_`d`t\u\uvvvvvr$   r   c                     || _         t          |                                 t          | j        j        ddg          | j         z   dz   S ) Generate INITIALIZE UPDATE APDU.r   r%   r*   )r   r>   r   INS_INIT_UPDATErN   rv   r   s     r"   r   zSCP02.gen_init_update_apdu  s?    ,diikk?DN4F1MNNQUQddgnnnr$   r   c                 R   | j                             |          }|d         | _        t          |d         | j                  | _        t                              | j                   |                     | j        | j	                   | j
        |d         k    rt          d          dS )z$Parse response to INITIALZIE UPDATE.r   r   r   card cryptogram doesn't matchN)
constr_iurparser   r6   rN   r}   r@   rA   r   r   r   r{   rC   r   resps      r"   r   zSCP02.parse_init_update_resp  s    $$X.."#34"4#6GGTW!!$"5t7JKKK4(9#:::<=== ;:r$   r   c                    |dz  rt          d          || _        | j        r1t          |                                 t
          | j        ddg          }n1t          |                     d          t
          | j        ddg          }| j                            || j        z   d          }t          |                     d          t
          | j        ddg          | j        z   |z   S )$Generate EXTERNAL AUTHENTICATE APDU.   z*R-MAC/R-ENC for SCP02 not implemented yet.r   r%   Tr   )	NotImplementedErrorr   r~   r>   r   INS_EXT_AUTHr}   rJ   r   )rC   r   headerrS   s       r"   r   zSCP02.gen_ext_auth_apdu)  s    D  	T%&RSSS,! 	XDIIKKt7JAqQRRFFDIIdOO\4;NPQSUVWWFg##FT-A$A4HHdiioo|T5H!RPQQTXThhknnnr$   r   c                    t                               dt          |                     | j        s|S t	          |          \  }}}}|dk    sJ |dk    sJ |dz  }|dz  }|d         }|dz  }	|dz  s
|t
          z  r$||                     d|	          k    s
J d            | j        r|}
|}n|d	z   }
|t
          z  }| j        	                    t          |g          |d
d         z   t          |
g          z   |z             }| j        r\t          j        | j        j        t          j        d          }|                    t%          |d	                    }t'          |          }|d	z  }t          |                     d|	          g          |d
d         z   t          |g          z   |z   |z   }|dk    s|dk    r|dz  }|S )z7Wrap Command APDU for SCP02: calculate MAC and encrypt.wrap_cmd_apdu(%s)      r   r1      FzCLA mismatchr%   r(   rn   r   Tr   r*   )r@   rA   r   r   r   r   r   r~   r}   rJ   r>   r   r   r   rL   r   r   r   r-   r   )rC   r   r   r   caselcler7   clar   mlcclacrS   ks                 r"   r   zSCP02._wrap_cmd_apdu6  s   (#d))444| 	K1$77r2t SyyyySyyyy
d

d
 1g4Z: 	?v 	?$))E2........! 	 CDD q&C<Dg##E4&MMD1I$=se$Lt$STT< 	clI>>A99U4^^,,DTB
adiib))*++d1Q3i7%++ELsR 199		GODr$   swrsp_apduc                     |S r   rk   )rC   r   r   s      r"   unwrap_rsp_apduzSCP02.unwrap_rsp_apduh  s    r$   )r   r   )r_   rd   re   rf   r   r   r   r
   r	   r   rt   r[   r>   r   r   r   r   r   ri   r   r   r   __classcell__r^   s   @r"   r   r      s       JJuuRyy0)F2BEE'NN%g-/?a/HJ[\a\abc\d\dJdf fJ ,ttTl;J* * * * *)E )e ) ) ) )*U *u * * * *w5 w% w w w wo o5 o o o o o
>u > > > >o o ou o o o o05 0e 0 0 0 0d% 5 U        r$   r   )AES)CMACcontextr,   c                 0   dt           dt           fd}|t          |          dz  }t                              dt	          |           t	          |          t	          |          |           |dz  }t          |           dk    sJ d| z   }d}d	}t          |          |k     rl|d
z   |                    dd          z   t          |g          z   |z   }	| |||	          z  }|dz  }|dk    rt          d          t          |          |k     l|d|         S )z<SCP03 Key Derivation Function as specified in Annex D 4.1.5.r   r7   c                 \    t          j        | |t                                                    S r   )r   r   r   digest)r   r7   s     r"   prfz!scp03_key_derivation.<locals>.prfu  s"    xT3''..000r$   Nr%   z5scp03_kdf(constant=%s, context=%s, base_key=%s, l=%u)r(   s              r$   r*   r   r   r   zOverflow in SP800 108 counter)r>   r   r@   rA   r   r   r{   )
r   r   r   r,   r   
output_lenlabelrI   dkinfos
             r"   scp03_key_derivationr   q  s@   1 1U 1 1 1 1 	yMMA
LLH#h--Y\]dYeYegjksgtgtvwxxxaJ x==A("E	A	B
b''J

wAu!5!55qc

BWL
cc(D!!!	Qv::<=== b''J

 kzk?r$   c                       e Zd ZdZdZdZdZdZdZdZ	dd	d
e
de
fdZde
fdZde
fdZddefdZdde
dede
fdZdde
dede
fdZdS )Scp03SessionKeysr*      r            r   rN   rO   r   r   c                     ||z   }t          | j        ||j                  | _        t          | j        ||j                  | _        t          | j        ||j                  | _        d| _	        d| _
        d S )N                   r   )r   DERIV_CONST_KDERIV_S_ENCrL   s_encDERIV_CONST_KDERIV_S_MACrS   s_macDERIV_CONST_KDERIV_S_RMACs_rmacmac_chaining_valueblock_nr)rC   rN   r   r   r   s        r"   r[   zScp03SessionKeys.__init__  so     >1)$*GR[R_``
)$*GR[R_``
*4+I7T]Tabb #/r$   r   c                     | j         |z   }t          j        | j        |t                                                    }|| _         |S )zCompute C-MAC for given to-be-transmitted APDU.
        Returns the full 16-byte MAC, caller must truncate it if needed for S8 mode.	ciphermod)r  r   r   r
  r   r   )rC   r   
cmac_inputcmac_vals       r"   	calc_cmaczScp03SessionKeys.calc_cmac  sB     ,t3
8DJ
cBBBIIKK"*r$   rdata_and_swc                 |    | j         |z   }t          j        | j        |t                                                    S )zCompute R-MAC for given received R-APDU data section.
        Returns the full 16-byte MAC, caller must truncate it if needed for S8 mode.r  )r  r   r   r  r   r   )rC   r  
rmac_inputs      r"   	calc_rmaczScp03SessionKeys.calc_rmac  s6     ,|;
xZ3???FFHHHr$   Fis_responsec                    |s| xj         dz  c_         | j                             | j        d          }|rd|dd         z   }t          dg| j        z            }t	          j        | j        t          j        |          }|                    |          }t          
                    dt          |          |t          |                     |S )zObtain the ICV value computed as described in 6.2.6.
        This method has two modes:
            * is_response=False for computing the ICV for C-ENC. Will pre-increment the counter.
            * is_response=False for computing the ICV for R-DEC.r(   r   r)   Nr   z'_get_icv(data=%s, is_resp=%s) -> icv=%s)r  r   rg   r>   r   r   r  r   r   r@   rA   r   )rC   r  r7   ivr!   r<   s         r"   _get_icvzScp03SessionKeys._get_icv  s    
  	MMQMM}%%dne<< 	& T!""X%DA3'((S\266nnT"">D		;X[\_X`X`aaa
r$   r7   r   c                     t          j        | j        t           j        |                     |                    }|                    |          S r   )r   r   r  r   r  r   rC   r7   r  r!   s       r"   _encryptzScp03SessionKeys._encrypt  7    S\4==3M3MNN~~d###r$   Tc                     t          j        | j        t           j        |                     |                    }|                    |          S r   )r   r   r  r   r  r?   r  s       r"   _decryptzScp03SessionKeys._decrypt  r   r$   Nrb   rc   )r_   rd   re   DERIV_CONST_AUTH_CGRAM_CARDDERIV_CONST_AUTH_CGRAM_HOSTDERIV_CONST_CARD_CHLG_GENr  r	  r  rg   r>   r[   r  r  rh   r  r  r"  rk   r$   r"   r   r     s       ")") '&& 'I. % Y^    e    Ie I I I I D    *$ $U $ $% $ $ $ $
$ $U $ $ $ $ $ $ $ $r$   r   c                   l    e Zd ZdZ ed ed          z  dez   ed          dez  d ed           z  d	 ed
           z  d e ed                    z            Z	ddgZ
 fdZdedefdZdedefdZd Zd%dee         defdZdefdZd&dedefdZd'ded edefd!Zd"ed#edefd$Z xZS )(SCP03zQSecure Channel Protocol (SCP) 03 as specified in GlobalPlatform v2.3 Amendment D.r   r   r      i_paramr   c                     | j         j        S r   _s_modectxs    r"   <lambda>zSCP03.<lambda>  s
    35< r$   r   c                     | j         j        S r   r+  r.  s    r"   r0  zSCP03.<lambda>  s
    CEL r$   sequence_counterr   0   ?   c                     |                     dd          | _        | j        | _         t                      j        |i | d S )Nr-  r%   )popr-  r   r   r[   r   s      r"   r[   zSCP03.__init__  sC    jj1--$)&)))))r$   r   r   c                     t          j        | j        j        t           j        d          }|                    |          S Nr  )r   r   rN   rX   r   r   r   s      r"   r   zSCP03.dek_encrypt  s.    +S\:FF~~i(((r$   r   c                     t          j        | j        j        t           j        d          }|                    |          S r8  )r   r   rN   rX   r   r?   r   s      r"   r   zSCP03.dek_decrypt  s.    +S\:FF~~j)))r$   c                    t                               dt          | j                  t          | j                             | j        | j        z   }t          | j        j        || j        j        | j	        dz            | _
        t          | j        j        || j        j        | j	        dz            | _        t                               dt          | j                  t          | j
                             d S )Nr   r%   )r,   r   )r@   rA   r   r   r   r   r}   r#  r
  r-  r   r$  r   )rC   r   s     r"   r   zSCP03._compute_cryptograms  s    =s4CV?W?WY\]a]pYqYqrrr%(;;3DG4WY`bfbibosws~  @A  tA   B   B   B3DG4WY`bfbibosws~  @A  tA   B   B   B?TEYAZAZ\_`d`t\u\uvvvvvr$   Nr   c           	         |
d| j         z  }t          |          | j         k    rt          d| j         z            || _        t	          |                                 t          | j        j        dt          |          g          |z   dz   S )r   Nr*   z$Host Challenge must be %u bytes longr   )	r-  r   r{   r   r>   r   r   rN   rv   r   s     r"   r   zSCP03.gen_init_update_apdu  s    !$t{2N~$+--CdkQRRR,diikk?DN4F3~K^K^_``cqqt{{{r$   r   c                    t          |          dvrt          d          | j                            || j                  }|d         | _        |d         | _        t          | j        | j	        | j                  | _
        t                              | j
                   |                                  | j        |d         k    rt          d          dS )	z$Parse response to INITIALIZE UPDATE.)   -   r   r3  z,Invalid length of Initialize Update Response)r-  r   r)  r   r   N)r   r{   r   r   r-  r   r)  r   rN   r   r}   r@   rA   r   r   r   s      r"   r   zSCP03.parse_init_update_resp  s    x== PPPKLLL$$Xdk$BB"#34I"4>43FH[\\TW!!###4(9#:::<=== ;:r$   r(   r   c                     || _         t          |                                 t          | j         d| j        g          }|                     || j        z   d          S )r   r   T)	skip_cenc)r   r>   r   r   r-  r   r   )rC   r   r   s      r"   r   zSCP03.gen_ext_auth_apdu	  sP    ,		\43F4;WXX!!&4+?"?4!PPPr$   Fr   r@  c                    t                               dt          |                     | j        s|S |d         }|d         }|d         }|d         }t	          |          \  }}}	}
|dk    sJ |	dk    sJ |dz  }|	dz  }	| j        ro|sm|dk    r| j        xj        dz  c_        nQt          |
d          }t          |          }|dk    rt          d	|z            | j                            |          }
|| j        z   }|dk    rt          d
|| j        fz            |dz  t          z  }t          |||||g          |
z   }| j                            |          }||d| j                 z  }|dk    s|dk    r|dz  }|S )z7Wrap Command APDU for SCP03: calculate MAC and encrypt.r   r   r(   r   r   r   r   r   z<Modified Lc (%u) would exceed maximum when appending paddingzDModified Lc (%u) would exceed maximum when appending %u bytes of macr   Nrn   r*   )r@   rA   r   r   r   r   r}   r  r-   r   r{   r  r-  r   r>   r  )rC   r   r@  r   insp1p2r   r   r   cmd_datarF   r   mclacmacs                  r"   r   zSCP03._wrap_cmd_apdu  s   (#d))444| 	K1g1g!W!W#5d#;#; r2x SyyyySyyyy
d

d
< 	9	 	9qyy   A%    $Hb11%%99$%cgi%jkkk7++K88 4;#::cgjlplwfxxyyy d
f$dCR-..9w  &&\dk\"" 199		GODr$   r   r   c                 P   t                               d||           | j        s| j        rJ |S |dk    r|d         dvr|S |d | j                  }|| j         d          }| j                            ||z             d | j                 }||k    rt          d|d|          | j        ry| j                            |          }t                               dt          |                     t          |          }t                               dt          |                     |S )	Nz#unwrap_rsp_apdu(sw=%s, rsp_apdu=%s)s    r   )b   c   z$R-MAC value not matching: received: z, computed: zdecrypted: %szresponse_data: %s)r@   rA   r   r   r-  r}   r  r{   r"  r   r4   )rC   r   r   response_datarmacrmac_expr   s          r"   r   zSCP03.unwrap_rsp_apduD  s4   
 	:BIII| 	|###OAl!:!:O 4;,/&7$$]R%788$+F8*W[W[W[]e]efggg< 	B((77ILL#i..999#I..MLL,c-.@.@AAAr$   r   r   rb   )r_   rd   re   rf   r   r   r   r
   	COptionalr   rs   r[   r>   r   r   r   r   r   r   ri   r   rh   r   r   r   r   s   @r"   r'  r'    s       [[ uuRyy0)F2BEE'NNT]^dTd(/G/G)H)HH)%%0H0H*I*II*99UU1XX+>+>>@ @J tI* * * * *
)E )e ) ) ) )*U *u * * * *w w w| |8E? |e | | | |>u > > > >Q Q Qu Q Q Q Q2 25 2T 2e 2 2 2 2h% 5 U        r$   r'  )r%   r   )1r   loggingtypingr   Cryptodome.Cipherr   r   Cryptodome.Util.strxorr   	constructr   r   r	   r
   rN  osmocom.constructr   osmocom.utilsr   osmocom.tlvr   r   pySim.utilsr   pySim.secure_channelr   	getLoggerr_   r@   setLevelDEBUGr>   ri   r#   r-   r4   r6   r   r   r   ABCrp   r   r   Cryptodome.Hashr   r   r   r'  rk   r$   r"   <module>r^     s  $ 


        ' ' ' ' ' ' ' ' ) ) ) ) ) ) 4 4 4 4 4 4 4 4 4 4 4 4 + + + + + + # # # # # #       ; ; ; ; ; ; ; ; * * * * * * . . . . . .		8	$	$    +5 +3 +% +E + + + +! !U !U ! ! ! !E e    2U 2U 2U 2U 2U 2U 2U 2Uh 	J J J J J- J J JZk k k k kC k k k^ " ! ! ! ! !             5 5 E hWZm gl    :A$ A$ A$ A$ A$ A$ A$ A$HL L L L LC L L L L Lr$   