hPdZddlZddlZddlZddlmZmZddlmZm Z m Z m Z m Z m Z ddlmZmZmZmZmZmZddlTddlmZddlmZee dd d d d d dddddddZe de z deed z deez Zee d dd d d Ze ed dee d dd d d z dez dez ed dez dez d ez d!ee d dd d "z Ze d#e d z d$ee d dd d dd %z Z e d#e d z d$ee d dd d dd &z Z!e d#e d z d$ee d dd d d 'z Z"e d(e z d)e z d*ez d+e z d,eej#j$e!e"d-z d.ed z d/ez Z%e d0e&e ez d1e z d2e z d3e z d4ee e d5e z d6e z z d7e z d8e&e ez d9e&e eed z Z'Gd:d;Z(Gd<d=e)Z*Gd>d?ej+Z,dd@l-m.Z.m/Z/m0Z0ddAl1m2Z2GdBdCej+Z3GdDdEe3ej+Z4GdFdGe3ej+Z5GdHdIe4Z6GdJdKe5Z7GdLdMe4Z8GdNdOe5Z9GdPdQe4Z:GdRdSe5Z;GdTdUe,ZzOtaAlgo.suaS4>%9::rkNrin_lenmultiplepaddingc2||zdkrdS|||zz }d|zS)z+Return padding bytes towards multiple of N.rrkr|)rrrpad_cnts ri _get_paddingzOtaAlgo._get_paddings3 H  ! !3fx/0  rkindatcZ|tt|||zS)z!Pad input bytes to multiple of N.)rrlen)rrrs ri_pad_to_multiplezOtaAlgo._pad_to_multiples'w++CJJ'JJJJrkc:|||j|S)z>Pad the given input data to multiple of the cipher block size.)rr)rhrrs ripad_to_blocksizezOtaAlgo.pad_to_blocksizes$$UDNGDDDrkrc||_dSrf)r)rhrs rirjzOtaAlgo.__init__s  rkc|jjSrf) __class__ruros ri__str__zOtaAlgo.__str__s ~&&rkrt)rurvrwr{ivr enum_name staticmethodrzrrgrrr_rjrr|rkrirrs :: ; ;BII!!S!C!#!!!\!KKKKsKKK\KEEeEcEEEEY'''''rkrceZdZdeffd ZdedefdZdedefdZej dedefdZ ej dedefdZ e deddfd Z xZS) rrrc|j|jkrtd|jd|jt|dSNzCannot use algorithm z with key for )rr`rsuperrjrhrrs rirjzOtaAlgoCrypt.__init__sR >T_ , ,*$...Z^ZiZijkk k rkdatarcV||}||S)zFEncrypt given input bytes using the key material given in constructor.)r_encrypt)rhr padded_datas riencryptzOtaAlgoCrypt.encrypts'++D11 }}[)))rkc,||S)zFDecrypt given input bytes using the key material given in constructor.)_decryptrhrs ridecryptzOtaAlgoCrypt.decrypts}}T"""rkcdSz:Actual implementation, to be implemented by derived class.Nr|rs rirzOtaAlgoCrypt._encryptrrkcdSrr|rs rirzOtaAlgoCrypt._decryptrrkc|D]}|j|jkr ||cS td|jz)zJResolve the class for the encryption algorithm of otak and instantiate it.z(No implementation for crypt algorithm %s)__subclasses__rr`rrbclsrsubcs rirnzOtaAlgoCrypt.from_keysets]&&(( " "D~00tDzz!!!1CdnTUUUrk)rurvrwr_rjrgrrrrrr classmethodrn __classcell__rs@rirrrrs0Y *5*U**** #5#U#### IEIeIIII IEIeIIIIVyV^VVV[VVVVVrkrrceZdZdeffd ZdedefdZdedefdZej dedefdZ e deddfd Z xZ S) rmrc|j|jkrtd|jd|jt |dSr)rrbrr`rrjrs rirjzOtaAlgoAuth.__init__sR >T^ + +*$...Z^ZiZijkk k rkrrcZ||}||}|S)zaCompute the CC/CR check bytes for the input data using key material given in constructor.)r_sign)rhrrsigs risignzOtaAlgoAuth.signs-++D11 jj%% rk cc_receivedc||}||kr0tdt|dt|ddS)zQCompute the CC/CR check bytes for the input data and compare against cc_received.z Received CC (z) != Computed CC ()N)rr~r)rhrrr2s ri check_sigzOtaAlgoAuth.check_sigsW YYt__ "  -#kJZJZJZJZ\_`b\c\c\c\c dee e  rkcdSrr|rs rirzOtaAlgoAuth._signs  rkc|D]}|j|jkr ||cS td|jz)zNResolve the class for the authentication algorithm of otak and instantiate it.z'No implementation for auth algorithm %s)rrrbrrs rirnzOtaAlgoAuth.from_keysets]&&(( " "D~//tDzz!!!0BT^STTTrk)rurvrwr_rjrgrrrrrrrnrrs@rirmrmsY %fUfffff    5    UyU]UUU[UUUUUrkrmc>eZdZdZdZdZdZdedefdZdedefdZ d S) OtaAlgoCryptDES;DES is insecure. For backwards compatibility with pre-Rel8rrErrrctj|jjtj|j}||Srf)rnewrrPMODE_CBCrrrhrciphers rirzOtaAlgoCryptDES._encrypt/ dg>>~~d###rkctj|jjtj|j}||Srf)rrrrPrrrrs rirzOtaAlgoCryptDES._decrypt rrkN) rurvrwrxnamerrrgrrr|rkrirrsmEE DII$E$e$$$$$E$e$$$$$$rkrc.eZdZdZdZdZdZdedefdZdS) OtaAlgoAuthDESrrrErrrctj|jjtj|j}||}|t|dz dSNr)rrrrQrrrrrhrrciphs rirzOtaAlgoAuthDES._signsG dg>>~~d##CIIMNN##rkN) rurvrwrxrrrrgrr|rkrirrsKEE DII$$5$$$$$$rkrc:eZdZdZdZdZdedefdZdedefdZdS) OtaAlgoCryptDES33DESrFrrrctj|jjtj|j}||Srf)rrrrPrrrrs rirzOtaAlgoCryptDES3._encrypt/$)-@@~~d###rkctj|jjtj|j}||Srf)rrrrPrrrrs rirzOtaAlgoCryptDES3._decrypt!rrkN rurvrwrrrrgrrr|rkrirrsg D!II$E$e$$$$$E$e$$$$$$rkrc*eZdZdZdZdZdedefdZdS)OtaAlgoAuthDES3rrFrrrctj|jjtj|j}||}|t|dz dSr)rrrrQrrrrrs rirzOtaAlgoAuthDES3._sign)sG$)-@@~~d##CIIMNN##rkNrurvrwrrrrgrr|rkrirr%sE D!II$$5$$$$$$rkrc:eZdZdZdZdZdedefdZdedefdZdS) OtaAlgoCryptAESrrHrrctj|jjtj|j}||Srf)rrrrPrrrrs rirzOtaAlgoCryptAES._encrypt2rrkctj|jjtj|j}||Srf)rrrrPrrrrs rirzOtaAlgoCryptAES._decrypt6rrkNrr|rkrirr.sg DII$E$e$$$$$E$e$$$$$$rkrc*eZdZdZdZdZdedefdZdS)OtaAlgoAuthAESrrIrrrctj|jjtd}|||}|t|dz dS)Nr) ciphermodmac_len)rrrrQrupdatedigestr)rhrcmacrs rirzOtaAlgoAuthAES._sign>sTx a@@@ D{{}}CIIMNN##rkNrr|rkrirr:sE DII$$5$$$$$$rkrc deZdZdZedez dez dedz dedz dez d ez d ee j d z z d e z Z ed ez de z dez dez dedz Zdededededef dZdededeeeeffdZdedededdedffdZdS) OtaDialectSmszDOTA dialect for SMS based transport, as described in 3GPP TS 31.115.rplrhlrRrrdrpcntrresponse_statuscc_rcrrSchlrOrPrQrrrcn||}d}|dr]d|zt|z}|j||jj}t|}t |}||z }|j|jd} |j|j d} d|z} |j | || | |d} |j dd| d dz} | | z|z}t||z}| d d|z}|d d kr#|j|}| |z|z}nj|d d kr4t!j|dz}| | ddz|z}n*|d dkr| |z}nt%d|d z|drH|j|}| |z}t|}| d d|z}n| |z}t|dkrt%d|S)Nrr9r)rBrC )rrOrPrQrRrbigrrr:r2r1lrr0rzDCannot encode command in a single SMS; Fragmentation not implemented)rrrsrrrgrar`rcrb hdr_constructbuildrdto_bytesrprzlibrKrr)rhrrRrOrlen_sigr len_cipherrrPrQr part_headpart_cnt envelope_datacplr2rKrs rirzOtaDialectSms.encode_cmdRsg'',, {  Ws4yy0Jj--j$*:NOOG'llG;;D GODlDO<<lDN;;7l&,,S3VYad-e-eff 9%%a//'2B2B1e2L2LL"H,t3 -  7* Q..>  z?d " " ..B$rMD0MM _ $ $J}-- :E$u~~a'?'??$FMM _ - -$tOMM3c*oEFF F {  6:%%m44D%,Mm$$CLLE22]BMM% 5M }   # #cdd drkencodedcX t|ddd}|dd}|dd}|j|}|j|}|dd}t|ddd} t|ddd} |dd}|d } | d d krO|dd} |dd} |dd|z|z| z}|j|| n]| d d kr*t|dd d}t| d dkr|} ntd| d z| dt| | z } |d| | fS)z;Decode an encoded (encrypted, signed) OTA SMS Command-APDU.TNrrrrrrrOr:r2r1rr0rrR) rz from_bytesrsrr parser rprNotImplementedErrorrr)rhrrrrrrhdr_decrrdrrOr2r temp_datacrc32_rxs ri decode_cmdzOtaDialectSms.decode_cmds (..!e44C#I344=D J..t44M $**955!!$~~hrrlE22..!""u55%abb) en z?d " "rr"B $D Q..:XELI I   2 . . . . _ $ $~~mBQB&7??H& % _ - - DD3c*oEFF F&SYYw&&'u~sD((rkrzOtaDialectSms.SmsResponsePacketrct|trt|}|ddkrtd|dzt j|\}}|dstd|dd}|j|}|drk|dd}|j |} || z} |j| }|ddkr|d d|d |d <| }|d d z } |d d kr| rtd| znm|d dkrI|dd} |dd} | | z|d| zdz} |j | |dntd|d z|jdkr6t|d r!t |d }nd}||fS)NrrzUnexpected UDL=0x%02xqzRPI 0x71 not found in UDHrr<rrSrrr=r0z%No RC/CC/DS requested, but len_sig=%ur2rrrzUnknown por_rc_cc_ds: %sr ) isinstanceryh2brrrhas_ieSmsResponsePacketrrsrr~rprrrr)rhrrOrudhd remainder rph_rhl_tarres ciphered_partdeciphrrudhrpl_rhl_tar_cntr_pcntr_stsdecs rirzOtaDialectSms.decode_resps3 dC  t99D 7d??4tAw>?? ?(3D99i{{4   :899 9m $**955 & ' "%abbMMZ'' 66F#f,I(..y99C7|q  &).&9.CL=.&IN#!Ie*r/ ~ - / / W#$Kg$UVVV W  D ( (rr(C)23B3 &889RZ[[;QQI I   3w< 8 8 8 8 :S=P PQQ Q  ( * *s3~3F/G/G *#))#n*=>>CCCSzrkN)rurvrwrxrrrBytesResponseStatusrr GreedyBytesr"rKICKID_CCr r_rgrrrrrrr|rkrirrFsNNuW}$V|$UU1XX~%eeAhh&v~0?&uuTXb['9'99-k9;;F5<sE#IuV|USXSXYZS[S[^\\MAyAuA4AuAQVAAAAF))y))5))U5$PUCU=V))))))))X3 33E3GhjrtGkHGI333333rkr)=rxr rstructtypingrr constructrrrrr r r r r rrrosmocom.construct osmocom.utilsr pySim.smsrr- HexAdapterr,r.rRC_CC_DSrr/r0KID_RCrOr:SmsCommandPacketPrefixed$SimFileAccessAndToolkitAppSpecParamsr_ Exceptionr~ABCrCryptodome.CipherrrrCryptodome.Hashrrrrrmrrrrrrrr|rkrirAsGG" """"""""KKKKKKKKKKKKKKKKMMMMMMMMMMMMMMMM$$$$$$(fQAQR#$aRS*+aQ2615+/ 111F/6-jjq.B.BB/ ;0G0GGII 4 AA!a @ @ @i GAJJ dd;;q>>a!*+1FFFFx GAJJDD 8 $${{1~~a1 6 6 66   ikk!nn$ttKKNNQ1VWij$%'''' 5Q'$${{1~~aYZlm()++++   5Q'$${{1~~!YZ[[[[  6-/'.))tx'8v:W:W X XXa.(4 66(.vohhv{>[>[.[.I&.P.A&.H.Nv.U.<]]6SYSYZ^_eZeZ_`fZfThTh>i>i/i.CF.J.3HHV[4Q4Q.Q.:88FKKX]X]^_X`X`LaLa;b;b.b(d(d$........,     I   <<<<<<<<4-,,,,,,,,, '''''cg'''8VVVVV7CGVVV>UUUUU'37UUU@ $ $ $ $ $l $ $ $$$$$$[$$$ $ $ $ $ $| $ $ $$$$$$k$$$ $ $ $ $ $l $ $ $$$$$$[$$$nnnnnJnnnnnrk