
    diP                        d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZmZmZmZmZmZ ddlT ddlmZ ddlmZ  ee	dd	d
dddddddddd          Z ede	z  d e ed
                    z  d ee          z            Z e ed
          dd	d
d          Z e ed
          dd	d
d          Z e ed
          dd	d
          Z  e ed          dez  dez  dez   ed
          dez  d ez  d!ez  d"e z  	  	        Z! ed# ed          z  d$ e ed          dd	ddd
%          z            Z" ed# ed          z  d$ e ed          dd	ddd
&          z            Z# ed# ed          z  d$ e ed          dd	dd'          z            Z$ ed(e
z  d)e	z  d*e!z  d+e"z  d, eej%        j&        e#e$d-          z  d. ed          z  d/ez            Z' ed0 e(e	e          z  d1e	z  d2e	z  d3e	z  d4 ee	 ed5e	z  d6e	z                      z  d7e	z  d8 e(e	e          z  d9 e(e	 e ed                              z            Z) G d: d;          Z* G d< d=e+          Z, G d> d?ej-                  Z.dd@l/m0Z0m1Z1m2Z2 ddAl3m4Z4  G dB dCej-                  Z5 G dD dEe5ej-                  Z6 G dF dGe5ej-                  Z7 G dH dIe6          Z8 G dJ dKe7          Z9 G dL dMe6          Z: G dN dOe7          Z; G dP dQe6          Z< G dR dSe7          Z= G dT dUe.          Z>dS )VzACode related to SIM/UICC OTA according to TS 102 225 + TS 31.115.    N)OptionalTuple)EnumInt8ubInt16ubStructBitsInteger	BitStruct)FlagPaddingSwitchthisPrefixedArrayGreedyRange)*)b2h)UserDataHeader                        	   
         )por_okrc_cc_ds_failedcntr_low	cntr_highcntr_blockedciphering_errorundefined_security_errorinsufficient_memorymore_time_neededtar_unknowninsufficient_security_levelactual_response_sms_submitactual_response_ussdnumber_of_commandslast_status_wordlast_response_data)no_rc_cc_dsrcccds)
no_countercounter_no_replay_or_seqcounter_must_be_highercounter_must_be_lower)no_porpor_requiredpor_only_when_errorcounter	cipheringrc_cc_dspor_in_submitpor_shall_be_cipheredpor_rc_cc_dsporkeyalgo)implicit
single_destriple_des_cbc2triple_des_cbc3aes_cbc)rD   rE   rF   rG   aes_cmac)rD   crc16crc32proprietarycmd_pkt_lencmd_hdr_lenspikickid)r2   r1   tarsecured_dataaccess_domainprio_level_of_tk_app_instmax_num_of_timersmax_text_length_for_menu_entrymenu_entriesidposmax_num_of_channelsmsl
tar_valuesc                   f    e Zd ZdZ	 ddedededededed	efd
Zed             Z	ed             Z
dS )	OtaKeysetzKThe OTA related data (key material, counter) to be used in encrypt/decrypt.r   
algo_cryptkic_idxrP   	algo_authkid_idxrQ   cntrc                     || _         t          |          | _        || _        || _        t          |          | _        || _        || _        d S N)r`   bytesrP   ra   rb   rQ   rc   rd   )selfr`   ra   rP   rb   rc   rQ   rd   s           7/home/jenkins/workspace/simtester-sanitize/pySim/ota.py__init__zOtaKeyset.__init__s   sC    $::"::			    c                 6    t                               |           S )z/Return an instance of the matching OtaAlgoAuth.)OtaAlgoAuthfrom_keysetrh   s    ri   authzOtaKeyset.auth}   s     &&t,,,rk   c                 6    t                               |           S )z0Return an instance of the matching OtaAlgoCrypt.)OtaAlgoCryptrn   ro   s    ri   cryptzOtaKeyset.crypt   s     ''---rk   Nr   )__name__
__module____qualname____doc__strintrg   rj   propertyrp   rs    rk   ri   r_   r_   q   s        UUGH 3  5 *-49AD    - - X- . . X. . .rk   r_   c                       e Zd ZdS )OtaCheckErrorN)ru   rv   rw   r|   rk   ri   r~   r~      s        Drk   r~   c                       e Zd ZdZdefdZej        dede	de
de	de	f
d            Zej        dede
de	deed	         ffd
            ZdS )
OtaDialectz1Base Class for OTA dialects such as SMS, BIP, ...rO   c                     |d         dk    rdS |d         dk    rdS |d         dk    rdS t          d|d         z            )	Nr=   r0   r   r1   r   r2   r   Invalid rc_cc_ds: %s)
ValueError)rh   rO   s     ri   _compute_sig_lenzOtaDialect._compute_sig_len   sV    z?m++1z?d""1z?d""1/#j/ABBBrk   otakrR   apdureturnc                     d S rf   r|   )rh   r   rR   rO   r   s        ri   
encode_cmdzOtaDialect.encode_cmd   s    rk   CompactRemoteRespc                     dS )a  Decode a response into a response packet and, if indicted (by a
        response status of `"por_ok"`) a decoded response.

        The response packet's common characteristics are not fully determined,
        and (so far) completely proprietary per dialect.Nr|   )rh   r   rO   r   s       ri   decode_respzOtaDialect.decode_resp         rk   N)ru   rv   rw   rx   SPIr   abcabstractmethodr_   rg   dictr   objectr   r   r|   rk   ri   r   r      s        ;;C3 C C C C 	y u 4 u QV     	<	 < <E <vxXkOlFm < < < < < <rk   r   )DESDES3AES)CMACc                       e Zd Z ed           ZdZdZeddededefd            Z	edde
dedefd	            Zdde
defd
ZdefdZd ZdS )OtaAlgoc                 2    t          dg| j        z            S )Nr   )rg   	blocksizero   s    ri   <lambda>zOtaAlgo.<lambda>   s    uaS4>%9:: rk   Nr   in_lenmultiplepaddingc                 2    | |z  dk    rdS || |z  z
  }d|z  S )z+Return padding bytes towards multiple of N.r   rk       r|   )r   r   r   pad_cnts       ri   _get_paddingzOtaAlgo._get_padding   s3     H!!3fx/0  rk   indatc                 Z    | t                               t          |           ||          z   S )z!Pad input bytes to multiple of N.)r   r   len)r   r   r   s      ri   _pad_to_multiplezOtaAlgo._pad_to_multiple   s'     w++CJJ'JJJJrk   c                 :    |                      || j        |          S )z>Pad the given input data to multiple of the cipher block size.)r   r   )rh   r   r   s      ri   pad_to_blocksizezOtaAlgo.pad_to_blocksize   s    $$UDNGDDDrk   r   c                     || _         d S rf   )r   )rh   r   s     ri   rj   zOtaAlgo.__init__   s    			rk   c                     | j         j        S rf   )	__class__ru   ro   s    ri   __str__zOtaAlgo.__str__   s    ~&&rk   rt   )ru   rv   rw   r{   ivr   	enum_namestaticmethodrz   r   rg   r   r   r_   rj   r   r|   rk   ri   r   r      s       	::	;	;BII! !S !C !# ! ! ! \! K K K Ks K K K \KE Ee Ec E E E EY    ' ' ' ' 'rk   r   c                        e Zd Zdef 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ededd fd	            Z xZS )
rr   r   c                     | j         |j        k    rt          d| j         d|j                  t                                          |           d S NzCannot use algorithm z with key for )r   r`   r   superrj   rh   r   r   s     ri   rj   zOtaAlgoCrypt.__init__   sR    >T_,,*$...Z^ZiZijkkkrk   datar   c                 V    |                      |          }|                     |          S )zFEncrypt given input bytes using the key material given in constructor.)r   _encrypt)rh   r   padded_datas      ri   encryptzOtaAlgoCrypt.encrypt   s'    ++D11}}[)))rk   c                 ,    |                      |          S )zFDecrypt given input bytes using the key material given in constructor.)_decryptrh   r   s     ri   decryptzOtaAlgoCrypt.decrypt   s    }}T"""rk   c                     dS z:Actual implementation, to be implemented by derived class.Nr|   r   s     ri   r   zOtaAlgoCrypt._encrypt   r   rk   c                     dS r   r|   r   s     ri   r   zOtaAlgoCrypt._decrypt   r   rk   c                     |                                  D ]}|j        |j        k    r ||          c S  t          d|j        z            )zJResolve the class for the encryption algorithm of otak and instantiate it.z(No implementation for crypt algorithm %s)__subclasses__r   r`   r   rb   clsr   subcs      ri   rn   zOtaAlgoCrypt.from_keyset   s]     &&(( 	" 	"D~00tDzz!!! 1CdnTUUUrk   )ru   rv   rw   r_   rj   rg   r   r   r   r   r   r   classmethodrn   __classcell__r   s   @ri   rr   rr      s0       Y      
*5 *U * * * *
#5 #U # # # # 	IE Ie I I I I 	IE Ie I I I I Vy V^ V V V [V V V V Vrk   rr   c                        e Zd Zdef 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dedd fd	            Z xZS )
rm   r   c                     | j         |j        k    rt          d| j         d|j                  t	                                          |           d S r   )r   rb   r   r`   r   rj   r   s     ri   rj   zOtaAlgoAuth.__init__   sR    >T^++*$...Z^ZiZijkkkrk   r   r   c                 Z    |                      |          }|                     |          }|S )zaCompute the CC/CR check bytes for the input data using key material
        given in constructor.)r   _sign)rh   r   r   sigs       ri   signzOtaAlgoAuth.sign   s-     ++D11jj%%
rk   cc_receivedc                     |                      |          }||k    r0t          dt          |          dt          |          d          dS )zQCompute the CC/CR check bytes for the input data and compare against cc_received.zReceived CC (z) != Computed CC ()N)r   r~   r   )rh   r   r   r2   s       ri   	check_sigzOtaAlgoAuth.check_sig   sW    YYt__"-#kJZJZJZJZ\_`b\c\c\c\c deee rk   c                     dS r   r|   r   s     ri   r   zOtaAlgoAuth._sign   s	     	rk   c                     |                                  D ]}|j        |j        k    r ||          c S  t          d|j        z            )zNResolve the class for the authentication algorithm of otak and instantiate it.z'No implementation for auth algorithm %s)r   r   rb   r   r   s      ri   rn   zOtaAlgoAuth.from_keyset   s]     &&(( 	" 	"D~//tDzz!!! 0BT^STTTrk   )ru   rv   rw   r_   rj   rg   r   r   r   r   r   r   rn   r   r   s   @ri   rm   rm      s        Y      
 %    fU f f f f f 	 5     Uy U] U U U [U U U U Urk   rm   c                   >    e Zd ZdZdZdZdZdedefdZdedefdZ	d	S )
OtaAlgoCryptDES;DES is insecure.  For backwards compatibility with pre-Rel8r   rE   r   r   r   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   newr   rP   MODE_CBCr   r   rh   r   ciphers      ri   r   zOtaAlgoCryptDES._encrypt  /    dg>>~~d###rk   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   r   r   rP   r   r   r   r   s      ri   r   zOtaAlgoCryptDES._decrypt  r   rk   N)
ru   rv   rw   rx   namer   r   rg   r   r   r|   rk   ri   r   r     sm        EEDII$E $e $ $ $ $$E $e $ $ $ $ $ $rk   r   c                   .    e Zd ZdZdZdZdZdedefdZdS )	OtaAlgoAuthDESr   r   rE   r   r   r   c                     t          j        | j        j        t           j        | j                  }|                    |          }|t          |          dz
  d          S Nr   )r   r   r   rQ   r   r   r   r   rh   r   r   ciphs       ri   r   zOtaAlgoAuthDES._sign  sG    dg>>~~d##CIIMNN##rk   N)	ru   rv   rw   rx   r   r   r   rg   r   r|   rk   ri   r   r     sK        EEDII$ $5 $ $ $ $ $ $rk   r   c                   :    e Zd ZdZdZdZdedefdZdedefdZdS )	OtaAlgoCryptDES33DESrF   r   r   r   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   r   r   rP   r   r   r   r   s      ri   r   zOtaAlgoCryptDES3._encrypt  /    $)-@@~~d###rk   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   r   r   rP   r   r   r   r   s      ri   r   zOtaAlgoCryptDES3._decrypt!  r   rk   N	ru   rv   rw   r   r   r   rg   r   r   r|   rk   ri   r   r     sg        D!II$E $e $ $ $ $$E $e $ $ $ $ $ $rk   r   c                   *    e Zd ZdZdZdZdedefdZdS )OtaAlgoAuthDES3r   rF   r   r   r   c                     t          j        | j        j        t           j        | j                  }|                    |          }|t          |          dz
  d          S r   )r   r   r   rQ   r   r   r   r   r   s       ri   r   zOtaAlgoAuthDES3._sign)  sG    $)-@@~~d##CIIMNN##rk   Nru   rv   rw   r   r   r   rg   r   r|   rk   ri   r   r   %  sE        D!II$ $5 $ $ $ $ $ $rk   r   c                   :    e Zd ZdZdZdZdedefdZdedefdZdS )	OtaAlgoCryptAESr   rH      r   r   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   r   r   rP   r   r   r   r   s      ri   r   zOtaAlgoCryptAES._encrypt2  r   rk   c                     t          j        | j        j        t           j        | j                  }|                    |          S rf   )r   r   r   rP   r   r   r   r   s      ri   r   zOtaAlgoCryptAES._decrypt6  r   rk   Nr   r|   rk   ri   r   r   .  sg        DII$E $e $ $ $ $$E $e $ $ $ $ $ $rk   r   c                   *    e Zd ZdZdZdZdedefdZdS )OtaAlgoAuthAESr   rI   r   r   r   c                     t          j        | j        j        t          d          }|                    |           |                                }|t          |          dz
  d          S )Nr   )	ciphermodmac_len)r   r   r   rQ   r   updatedigestr   )rh   r   cmacr   s       ri   r   zOtaAlgoAuthAES._sign>  sT    x	a@@@D{{}}CIIMNN##rk   Nr   r|   rk   ri   r   r   :  sE        DII$ $5 $ $ $ $ $ $rk   r   c                   d   e Zd ZdZ edez  dez  d ed          z  d ed          z  dez  d	ez  d
 ee	j
        dz
            z  dez            Z edez  dez  dez  dez  d ed          z            Zdededededef
dZdededeeeef         fdZdedededded         ffdZdS )OtaDialectSmszDOTA dialect for SMS based transport, as described in 3GPP TS 31.115.rplrhlrR   r   rd   r   pcntrresponse_statuscc_rcr   rS   chlrO   rP   rQ   r   r   r   c                 n   |                      |          }d}|d         r]d|z   t          |          z   }|j                            ||j        j                  }t          |          }t          |          }||z  }|j        |j        d}	|j        |j	        d}
d|z   }| j
                            |||	|
|d          }|j                            dd          |                    d	d          z   }||z   |z   }t          |          |z   }|                    d
d          |z   }|d         dk    r#|j                            |          }||z   |z   }nj|d         dk    r4t!          j        |          dz  }||                    dd          z   |z   }n*|d         dk    r||z   }nt%          d|d         z            |d         rH|j                            |          }||z   }t          |          }|                    d
d          |z   }n||z   }t          |          dk    rt%          d          |S )Nr   r<   r   )rB   rC      )r  rO   rP   rQ   rR   r   bigr   r   r=   r2   r1   l    r   r0   r      zDCannot encode command in a single SMS; Fragmentation not implemented)r   r   rs   r   r   rg   ra   r`   rc   rb   hdr_constructbuildrd   to_bytesrp   r   zlibrK   r   r   )rh   r   rR   rO   r   len_sigr   
len_cipherr   rP   rQ   r  	part_headpart_cntenvelope_datacplr2   rK   r   s                      ri   r   zOtaDialectSms.encode_cmdR  sg   '',,{ 	Ws4yy0Jj--j$*:NOOG'llG;;DGODlDO<<lDN;; 7l &,,S3VYad-e-eff	 9%%a//'2B2B1e2L2LL "H,t3
 -  7*Q..> z?d""..B$rMD0MM_$$J}--
:E$u~~a'?'??$FMM_--$tOMM3c*oEFFF
 { 	6:%%m44D%,Mm$$CLLE22]BMM%5M }##cdddrk   encodedc                 X   	 t                               |dd         d          }|dd         }|dd         }|j                            |          }| j                            |          }|dd         }t                               |dd         d          }	t                               |dd         d          }
|dd         }|d	         }|d
         dk    rO|dd         }|dd         }|                    dd          |z   |z   |z   }|j                            ||           n]|d
         dk    r*t                               |dd         d          }t          |d
         dk    r|}nt          d|d
         z            |dt          |          |
z
           }|d         ||fS )z;Decode an encoded (encrypted, signed) OTA SMS Command-APDU.TNr   r  r   r   r   r   rO   r=   r2   r1   r   r0   r   rR   )rz   
from_bytesrs   r   r
  parser  rp   r   NotImplementedErrorr   r   )rh   r   r  r  r  r   r  hdr_decr  rd   r   rO   r2   r   	temp_datacrc32_rxs                   ri   
decode_cmdzOtaDialectSms.decode_cmd  s   	(..!e44C#I344=D J..t44M $**955 !!$~~hrrlE22..!""u55%abb)enz?d""rr"B $DQ..:XELII	2...._$$~~mBQB&7??H &%_-- DD3c*oEFFF&SYYw&&'u~sD((rk   r   zOtaDialectSms.SmsResponsePacketr   c                    t          |t                    rt          |          }|d         dk    rt          d|d         z            t	          j        |          \  }}|                    d          st          d          |d d         }| j                            |          }|d         rk|dd          }|j	        
                    |          }	||	z   }
| j                            |
          }|d         dk    r|d	         d |d                   |d	<   |
}|d
         dz
  }|d         dk    r|rt          d|z            nm|d         dk    rI|d d         }|d d         }||z   |d|z   d          z   }
|j                            |
|d                    nt          d|d         z            |j        dk    r6t          |d	                   r!t                               |d	                   }nd }||fS )Nr   r   zUnexpected UDL=0x%02xq   zRPI 0x71 not found in UDHr   r?   r  rS   r  r   r@   r0   z%No RC/CC/DS requested, but len_sig=%ur2   r   r  r  zUnknown por_rc_cc_ds: %sr    )
isinstancery   h2br   r   r  has_ieSmsResponsePacketr  rs   r   r~   rp   r   r  r   r   )rh   r   rO   r   udhd	remainderrph_rhl_tarresciphered_partdeciphr  r  udhrpl_rhl_tar_cntr_pcntr_stsdecs                  ri   r   zOtaDialectSms.decode_resp  s3   dC   	t99D 7d??4tAw>???(3D99i{{4   	:8999m$**955&' 
	"%abbMMZ''66F#f,I(..y99C7|q  &).&9.CL=.&IN#!I e*r/~-// W#$Kg$UVVVW D(( rr(C)23B3&889RZ[[;QQII	3w<8888   :S=P PQQQ (**s3~3F/G/G*#))#n*=>>CCCSzrk   N)ru   rv   rw   rx   r   r   r   BytesResponseStatusr   r  GreedyBytesr"  r   KICKID_CCr
  r_   rg   r   r   r   r  r   r   r|   rk   ri   r   r   F  s       NNuW}$V|$UU1XX~%eeAhh&v~0?&uuTXb['9'99-k9; ; F5<sE#IuV|USXSXYZS[S[^\\MAy Au A4 Au AQV A A A AF))y ))5 ))U5$PUCU=V )) )) )) ))X3	 3 3E 3Ghjr  tG  kH  GI 3 3 3 3 3 3rk   r   )?rx   r  r   structtypingr   r   	constructr   r   r   r   r	   r
   r   r   r   r   r   r   osmocom.constructosmocom.utilsr   	pySim.smsr   r-  
HexAdapterr,  r.  r   RC_CC_DSCNTR_REQPOR_REQr   r/  r0  KID_RCrO   r=   SmsCommandPacketPrefixed$SimFileAccessAndToolkitAppSpecParamsr_   	Exceptionr~   ABCr   Cryptodome.Cipherr   r   r   Cryptodome.Hashr   r   rr   rm   r   r   r   r   r   r   r   r|   rk   ri   <module>rC     s   G G"  



  " " " " " " " " K K K K K K K K K K K K K K K K M M M M M M M M M M M M M M M M           $ $ $ $ $ $( fQAQR#$aRS*+aQ2615+/1 1 1 F/6-jjq.B.BB/

;0G0GGI I  4AA!a@@@4A1qabz{|||
${{1~~aaQ
O
O
O iGAJJhxGAJJDD 8	'M  ikk!nn$ttKKNNQ1VWij$%' ' ' '  
5Q'$${{1~~aYZlm()+ + + +
 
 
5Q'$${{1~~!YZ[[[[
 
 6-/'.))tx'8v:W:W X XXa.(46 6  (.vohhv{>[>[.[.I&.P.A&.H.Nv.U.<]]6SYSYZ^_eZeZ_`fZfTh Th >i >i /i.CF.J.3HHV[4Q4Q.Q.:88FKKX]X]^_X`X`LaLa;b;b.b(d (d $. . . . . . . .,	 	 	 	 	I 	 	 	< < < < < < < <4 - , , , , , , , , ,            ' ' ' ' 'cg ' ' '8V V V V V7CG V V V>U U U U U'37 U U U@$ $ $ $ $l $ $ $$ $ $ $ $[ $ $ $
$ 
$ 
$ 
$ 
$| 
$ 
$ 
$$ $ $ $ $k $ $ $
$ 
$ 
$ 
$ 
$l 
$ 
$ 
$$ $ $ $ $[ $ $ $n n n n nJ n n n n nrk   