123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837 |
- /*
- * srtp_driver.c
- *
- * a test driver for libSRTP
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
- /*
- *
- * Copyright (c) 2001-2017, Cisco Systems, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * Neither the name of the Cisco Systems, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include <string.h> /* for memcpy() */
- #include <time.h> /* for clock() */
- #include <stdlib.h> /* for malloc(), free() */
- #include <stdio.h> /* for print(), fflush() */
- #include "getopt_s.h" /* for local getopt() */
- #include "srtp_priv.h"
- #include "util.h"
- #ifdef HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #elif defined HAVE_WINSOCK2_H
- #include <winsock2.h>
- #endif
- #define PRINT_REFERENCE_PACKET 1
- srtp_err_status_t srtp_validate(void);
- #ifdef GCM
- srtp_err_status_t srtp_validate_gcm(void);
- #endif
- srtp_err_status_t srtp_validate_encrypted_extensions_headers(void);
- #ifdef GCM
- srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm(void);
- #endif
- srtp_err_status_t srtp_validate_aes_256(void);
- srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list);
- srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list);
- srtp_err_status_t srtp_test_empty_payload(void);
- #ifdef GCM
- srtp_err_status_t srtp_test_empty_payload_gcm(void);
- #endif
- srtp_err_status_t srtp_test_remove_stream(void);
- srtp_err_status_t srtp_test_update(void);
- srtp_err_status_t srtp_test_protect_trailer_length(void);
- srtp_err_status_t srtp_test_protect_rtcp_trailer_length(void);
- srtp_err_status_t srtp_test_get_roc(void);
- srtp_err_status_t srtp_test_set_receiver_roc(void);
- srtp_err_status_t srtp_test_set_sender_roc(void);
- double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
- double srtp_rejections_per_second(int msg_len_octets,
- const srtp_policy_t *policy);
- void srtp_do_timing(const srtp_policy_t *policy);
- void srtp_do_rejection_timing(const srtp_policy_t *policy);
- srtp_err_status_t srtp_test(const srtp_policy_t *policy,
- int extension_header,
- int mki_index);
- srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index);
- srtp_err_status_t srtp_session_print_policy(srtp_t srtp);
- srtp_err_status_t srtp_print_policy(const srtp_policy_t *policy);
- char *srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
- double mips_estimate(int num_trials, int *ignore);
- #define TEST_MKI_ID_SIZE 4
- extern uint8_t test_key[46];
- extern uint8_t test_key_2[46];
- extern uint8_t test_mki_id[TEST_MKI_ID_SIZE];
- extern uint8_t test_mki_id_2[TEST_MKI_ID_SIZE];
- // clang-format off
- srtp_master_key_t master_key_1 = {
- test_key,
- test_mki_id,
- TEST_MKI_ID_SIZE
- };
- srtp_master_key_t master_key_2 = {
- test_key_2,
- test_mki_id_2,
- TEST_MKI_ID_SIZE
- };
- srtp_master_key_t *test_keys[2] = {
- &master_key_1,
- &master_key_2
- };
- // clang-format on
- void usage(char *prog_name)
- {
- printf("usage: %s [ -t ][ -c ][ -v ][ -o ][-d <debug_module> ]* [ -l ]\n"
- " -t run timing test\n"
- " -r run rejection timing test\n"
- " -c run codec timing test\n"
- " -v run validation tests\n"
- " -o output logging to stdout\n"
- " -d <mod> turn on debugging module <mod>\n"
- " -l list debugging modules\n",
- prog_name);
- exit(1);
- }
- void log_handler(srtp_log_level_t level, const char *msg, void *data)
- {
- char level_char = '?';
- switch (level) {
- case srtp_log_level_error:
- level_char = 'e';
- break;
- case srtp_log_level_warning:
- level_char = 'w';
- break;
- case srtp_log_level_info:
- level_char = 'i';
- break;
- case srtp_log_level_debug:
- level_char = 'd';
- break;
- }
- printf("SRTP-LOG [%c]: %s\n", level_char, msg);
- }
- /*
- * The policy_array is a null-terminated array of policy structs. it
- * is declared at the end of this file
- */
- extern const srtp_policy_t *policy_array[];
- /* the wildcard_policy is declared below; it has a wildcard ssrc */
- extern const srtp_policy_t wildcard_policy;
- /*
- * mod_driver debug module - debugging module for this test driver
- *
- * we use the crypto_kernel debugging system in this driver, which
- * makes the interface uniform and increases portability
- */
- srtp_debug_module_t mod_driver = {
- 0, /* debugging is off by default */
- "driver" /* printable name for module */
- };
- int main(int argc, char *argv[])
- {
- int q;
- unsigned do_timing_test = 0;
- unsigned do_rejection_test = 0;
- unsigned do_codec_timing = 0;
- unsigned do_validation = 0;
- unsigned do_list_mods = 0;
- unsigned do_log_stdout = 0;
- srtp_err_status_t status;
- /*
- * verify that the compiler has interpreted the header data
- * structure srtp_hdr_t correctly
- */
- if (sizeof(srtp_hdr_t) != 12) {
- printf("error: srtp_hdr_t has incorrect size"
- "(size is %ld bytes, expected 12)\n",
- (long)sizeof(srtp_hdr_t));
- exit(1);
- }
- /* initialize srtp library */
- status = srtp_init();
- if (status) {
- printf("error: srtp init failed with error code %d\n", status);
- exit(1);
- }
- /* load srtp_driver debug module */
- status = srtp_crypto_kernel_load_debug_module(&mod_driver);
- if (status) {
- printf("error: load of srtp_driver debug module failed "
- "with error code %d\n",
- status);
- exit(1);
- }
- /* process input arguments */
- while (1) {
- q = getopt_s(argc, argv, "trcvold:");
- if (q == -1) {
- break;
- }
- switch (q) {
- case 't':
- do_timing_test = 1;
- break;
- case 'r':
- do_rejection_test = 1;
- break;
- case 'c':
- do_codec_timing = 1;
- break;
- case 'v':
- do_validation = 1;
- break;
- case 'o':
- do_log_stdout = 1;
- break;
- case 'l':
- do_list_mods = 1;
- break;
- case 'd':
- status = srtp_set_debug_module(optarg_s, 1);
- if (status) {
- printf("error: set debug module (%s) failed\n", optarg_s);
- exit(1);
- }
- break;
- default:
- usage(argv[0]);
- }
- }
- if (!do_validation && !do_timing_test && !do_codec_timing &&
- !do_list_mods && !do_rejection_test) {
- usage(argv[0]);
- }
- if (do_log_stdout) {
- status = srtp_install_log_handler(log_handler, NULL);
- if (status) {
- printf("error: install log handler failed\n");
- exit(1);
- }
- }
- if (do_list_mods) {
- status = srtp_list_debug_modules();
- if (status) {
- printf("error: list of debug modules failed\n");
- exit(1);
- }
- }
- if (do_validation) {
- const srtp_policy_t **policy = policy_array;
- srtp_policy_t *big_policy;
- /* loop over policy array, testing srtp and srtcp for each policy */
- while (*policy != NULL) {
- printf("testing srtp_protect and srtp_unprotect\n");
- if (srtp_test(*policy, 0, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect and srtp_unprotect with encrypted "
- "extensions headers\n");
- if (srtp_test(*policy, 1, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
- if (srtcp_test(*policy, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI "
- "index set to 0\n");
- if (srtp_test(*policy, 0, 0) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI "
- "index set to 1\n");
- if (srtp_test(*policy, 0, 1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI "
- "index set to 0\n");
- if (srtcp_test(*policy, 0) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI "
- "index set to 1\n");
- if (srtcp_test(*policy, 1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- policy++;
- }
- /* create a big policy list and run tests on it */
- status = srtp_create_big_policy(&big_policy);
- if (status) {
- printf("unexpected failure with error code %d\n", status);
- exit(1);
- }
- printf("testing srtp_protect and srtp_unprotect with big policy\n");
- if (srtp_test(big_policy, 0, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect and srtp_unprotect with big policy and "
- "encrypted extensions headers\n");
- if (srtp_test(big_policy, 1, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- status = srtp_dealloc_big_policy(big_policy);
- if (status) {
- printf("unexpected failure with error code %d\n", status);
- exit(1);
- }
- /* run test on wildcard policy */
- printf("testing srtp_protect and srtp_unprotect on "
- "wildcard ssrc policy\n");
- if (srtp_test(&wildcard_policy, 0, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_protect and srtp_unprotect on "
- "wildcard ssrc policy and encrypted extensions headers\n");
- if (srtp_test(&wildcard_policy, 1, -1) == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- /*
- * run validation test against the reference packets - note
- * that this test only covers the default policy
- */
- printf("testing srtp_protect and srtp_unprotect against "
- "reference packet\n");
- if (srtp_validate() == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- #ifdef GCM
- printf("testing srtp_protect and srtp_unprotect against "
- "reference packet using GCM\n");
- if (srtp_validate_gcm() == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- #endif
- printf("testing srtp_protect and srtp_unprotect against "
- "reference packet with encrypted extensions headers\n");
- if (srtp_validate_encrypted_extensions_headers() == srtp_err_status_ok)
- printf("passed\n\n");
- else {
- printf("failed\n");
- exit(1);
- }
- #ifdef GCM
- printf("testing srtp_protect and srtp_unprotect against "
- "reference packet with encrypted extension headers (GCM)\n");
- if (srtp_validate_encrypted_extensions_headers_gcm() ==
- srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- #endif
- /*
- * run validation test against the reference packets for
- * AES-256
- */
- printf("testing srtp_protect and srtp_unprotect against "
- "reference packet (AES-256)\n");
- if (srtp_validate_aes_256() == srtp_err_status_ok) {
- printf("passed\n\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- /*
- * test packets with empty payload
- */
- printf("testing srtp_protect and srtp_unprotect against "
- "packet with empty payload\n");
- if (srtp_test_empty_payload() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- #ifdef GCM
- printf("testing srtp_protect and srtp_unprotect against "
- "packet with empty payload (GCM)\n");
- if (srtp_test_empty_payload_gcm() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- #endif
- /*
- * test the function srtp_remove_stream()
- */
- printf("testing srtp_remove_stream()...");
- if (srtp_test_remove_stream() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- /*
- * test the function srtp_update()
- */
- printf("testing srtp_update()...");
- if (srtp_test_update() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- /*
- * test the functions srtp_get_protect_trailer_length
- * and srtp_get_protect_rtcp_trailer_length
- */
- printf("testing srtp_get_protect_trailer_length()...");
- if (srtp_test_protect_trailer_length() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_get_protect_rtcp_trailer_length()...");
- if (srtp_test_protect_rtcp_trailer_length() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_test_get_roc()...");
- if (srtp_test_get_roc() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_test_set_receiver_roc()...");
- if (srtp_test_set_receiver_roc() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- printf("testing srtp_test_set_sender_roc()...");
- if (srtp_test_set_sender_roc() == srtp_err_status_ok) {
- printf("passed\n");
- } else {
- printf("failed\n");
- exit(1);
- }
- }
- if (do_timing_test) {
- const srtp_policy_t **policy = policy_array;
- /* loop over policies, run timing test for each */
- while (*policy != NULL) {
- srtp_print_policy(*policy);
- srtp_do_timing(*policy);
- policy++;
- }
- }
- if (do_rejection_test) {
- const srtp_policy_t **policy = policy_array;
- /* loop over policies, run rejection timing test for each */
- while (*policy != NULL) {
- srtp_print_policy(*policy);
- srtp_do_rejection_timing(*policy);
- policy++;
- }
- }
- if (do_codec_timing) {
- srtp_policy_t policy;
- int ignore;
- double mips_value = mips_estimate(1000000000, &ignore);
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xdecafbad;
- policy.key = test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- printf("mips estimate: %e\n", mips_value);
- printf("testing srtp processing time for voice codecs:\n");
- printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
- printf("G.711\t\t%d\t\t\t%e\n", 80,
- (double)mips_value * (80 * 8) /
- srtp_bits_per_second(80, &policy) / .01);
- printf("G.711\t\t%d\t\t\t%e\n", 160,
- (double)mips_value * (160 * 8) /
- srtp_bits_per_second(160, &policy) / .02);
- printf("G.726-32\t%d\t\t\t%e\n", 40,
- (double)mips_value * (40 * 8) /
- srtp_bits_per_second(40, &policy) / .01);
- printf("G.726-32\t%d\t\t\t%e\n", 80,
- (double)mips_value * (80 * 8) /
- srtp_bits_per_second(80, &policy) / .02);
- printf("G.729\t\t%d\t\t\t%e\n", 10,
- (double)mips_value * (10 * 8) /
- srtp_bits_per_second(10, &policy) / .01);
- printf("G.729\t\t%d\t\t\t%e\n", 20,
- (double)mips_value * (20 * 8) /
- srtp_bits_per_second(20, &policy) / .02);
- printf("Wideband\t%d\t\t\t%e\n", 320,
- (double)mips_value * (320 * 8) /
- srtp_bits_per_second(320, &policy) / .01);
- printf("Wideband\t%d\t\t\t%e\n", 640,
- (double)mips_value * (640 * 8) /
- srtp_bits_per_second(640, &policy) / .02);
- }
- status = srtp_shutdown();
- if (status) {
- printf("error: srtp shutdown failed with error code %d\n", status);
- exit(1);
- }
- return 0;
- }
- /*
- * srtp_create_test_packet(len, ssrc) returns a pointer to a
- * (malloced) example RTP packet whose data field has the length given
- * by pkt_octet_len and the SSRC value ssrc. The total length of the
- * packet is twelve octets longer, since the header is at the
- * beginning. There is room at the end of the packet for a trailer,
- * and the four octets following the packet are filled with 0xff
- * values to enable testing for overwrites.
- *
- * note that the location of the test packet can (and should) be
- * deallocated with the free() call once it is no longer needed.
- */
- srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len,
- uint32_t ssrc,
- int *pkt_len)
- {
- int i;
- uint8_t *buffer;
- srtp_hdr_t *hdr;
- int bytes_in_hdr = 12;
- /* allocate memory for test packet */
- hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
- SRTP_MAX_TRAILER_LEN + 4);
- if (!hdr) {
- return NULL;
- }
- hdr->version = 2; /* RTP version two */
- hdr->p = 0; /* no padding needed */
- hdr->x = 0; /* no header extension */
- hdr->cc = 0; /* no CSRCs */
- hdr->m = 0; /* marker bit */
- hdr->pt = 0xf; /* payload type */
- hdr->seq = htons(0x1234); /* sequence number */
- hdr->ts = htonl(0xdecafbad); /* timestamp */
- hdr->ssrc = htonl(ssrc); /* synch. source */
- buffer = (uint8_t *)hdr;
- buffer += bytes_in_hdr;
- /* set RTP data to 0xab */
- for (i = 0; i < pkt_octet_len; i++) {
- *buffer++ = 0xab;
- }
- /* set post-data value to 0xffff to enable overrun checking */
- for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
- *buffer++ = 0xff;
- }
- *pkt_len = bytes_in_hdr + pkt_octet_len;
- return hdr;
- }
- static srtp_hdr_t *srtp_create_test_packet_extended(int pkt_octet_len,
- uint32_t ssrc,
- uint16_t seq,
- uint32_t ts,
- int *pkt_len)
- {
- srtp_hdr_t *hdr;
- hdr = srtp_create_test_packet(pkt_octet_len, ssrc, pkt_len);
- if (hdr == NULL)
- return hdr;
- hdr->seq = htons(seq);
- hdr->ts = htonl(ts);
- return hdr;
- }
- srtp_hdr_t *srtp_create_test_packet_ext_hdr(int pkt_octet_len,
- uint32_t ssrc,
- int *pkt_len)
- {
- int i;
- uint8_t *buffer;
- srtp_hdr_t *hdr;
- int bytes_in_hdr = 12;
- uint8_t extension_header[12] = { /* one-byte header */
- 0xbe, 0xde,
- /* size */
- 0x00, 0x02,
- /* id 1, length 1 (i.e. 2 bytes) */
- 0x11,
- /* payload */
- 0xca, 0xfe,
- /* padding */
- 0x00,
- /* id 2, length 0 (i.e. 1 byte) */
- 0x20,
- /* payload */
- 0xba,
- /* padding */
- 0x00, 0x00
- };
- /* allocate memory for test packet */
- hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
- sizeof(extension_header) + SRTP_MAX_TRAILER_LEN +
- 4);
- if (!hdr)
- return NULL;
- hdr->version = 2; /* RTP version two */
- hdr->p = 0; /* no padding needed */
- hdr->x = 1; /* no header extension */
- hdr->cc = 0; /* no CSRCs */
- hdr->m = 0; /* marker bit */
- hdr->pt = 0xf; /* payload type */
- hdr->seq = htons(0x1234); /* sequence number */
- hdr->ts = htonl(0xdecafbad); /* timestamp */
- hdr->ssrc = htonl(ssrc); /* synch. source */
- buffer = (uint8_t *)hdr;
- buffer += bytes_in_hdr;
- memcpy(buffer, extension_header, sizeof(extension_header));
- buffer += sizeof(extension_header);
- /* set RTP data to 0xab */
- for (i = 0; i < pkt_octet_len; i++)
- *buffer++ = 0xab;
- /* set post-data value to 0xffff to enable overrun checking */
- for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++)
- *buffer++ = 0xff;
- *pkt_len = bytes_in_hdr + sizeof(extension_header) + pkt_octet_len;
- return hdr;
- }
- void srtp_do_timing(const srtp_policy_t *policy)
- {
- int len;
- /*
- * note: the output of this function is formatted so that it
- * can be used in gnuplot. '#' indicates a comment, and "\r\n"
- * terminates a record
- */
- printf("# testing srtp throughput:\r\n");
- printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
- for (len = 16; len <= 2048; len *= 2) {
- printf("%d\t\t\t%f\r\n", len,
- srtp_bits_per_second(len, policy) / 1.0E6);
- }
- /* these extra linefeeds let gnuplot know that a dataset is done */
- printf("\r\n\r\n");
- }
- void srtp_do_rejection_timing(const srtp_policy_t *policy)
- {
- int len;
- /*
- * note: the output of this function is formatted so that it
- * can be used in gnuplot. '#' indicates a comment, and "\r\n"
- * terminates a record
- */
- printf("# testing srtp rejection throughput:\r\n");
- printf("# mesg length (octets)\trejections per second\r\n");
- for (len = 8; len <= 2048; len *= 2) {
- printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
- }
- /* these extra linefeeds let gnuplot know that a dataset is done */
- printf("\r\n\r\n");
- }
- #define MAX_MSG_LEN 1024
- double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy)
- {
- srtp_t srtp;
- srtp_hdr_t *mesg;
- int i;
- clock_t timer;
- int num_trials = 100000;
- int input_len, len;
- uint32_t ssrc;
- srtp_err_status_t status;
- /*
- * allocate and initialize an srtp session
- */
- status = srtp_create(&srtp, policy);
- if (status) {
- printf("error: srtp_create() failed with error code %d\n", status);
- exit(1);
- }
- /*
- * if the ssrc is unspecified, use a predetermined one
- */
- if (policy->ssrc.type != ssrc_specific) {
- ssrc = 0xdeadbeef;
- } else {
- ssrc = policy->ssrc.value;
- }
- /*
- * create a test packet
- */
- mesg = srtp_create_test_packet(msg_len_octets, ssrc, &input_len);
- if (mesg == NULL) {
- return 0.0; /* indicate failure by returning zero */
- }
- timer = clock();
- for (i = 0; i < num_trials; i++) {
- len = input_len;
- /* srtp protect message */
- status = srtp_protect(srtp, mesg, &len);
- if (status) {
- printf("error: srtp_protect() failed with error code %d\n", status);
- exit(1);
- }
- /* increment message number */
- {
- /* hack sequence to avoid problems with macros for htons/ntohs on
- * some systems */
- short new_seq = ntohs(mesg->seq) + 1;
- mesg->seq = htons(new_seq);
- }
- }
- timer = clock() - timer;
- free(mesg);
- status = srtp_dealloc(srtp);
- if (status) {
- printf("error: srtp_dealloc() failed with error code %d\n", status);
- exit(1);
- }
- return (double)(msg_len_octets)*8 * num_trials * CLOCKS_PER_SEC / timer;
- }
- double srtp_rejections_per_second(int msg_len_octets,
- const srtp_policy_t *policy)
- {
- srtp_ctx_t *srtp;
- srtp_hdr_t *mesg;
- int i;
- int len;
- clock_t timer;
- int num_trials = 1000000;
- uint32_t ssrc = policy->ssrc.value;
- srtp_err_status_t status;
- /*
- * allocate and initialize an srtp session
- */
- status = srtp_create(&srtp, policy);
- if (status) {
- printf("error: srtp_create() failed with error code %d\n", status);
- exit(1);
- }
- mesg = srtp_create_test_packet(msg_len_octets, ssrc, &len);
- if (mesg == NULL) {
- return 0.0; /* indicate failure by returning zero */
- }
- srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
- timer = clock();
- for (i = 0; i < num_trials; i++) {
- len = msg_len_octets;
- srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
- }
- timer = clock() - timer;
- free(mesg);
- status = srtp_dealloc(srtp);
- if (status) {
- printf("error: srtp_dealloc() failed with error code %d\n", status);
- exit(1);
- }
- return (double)num_trials * CLOCKS_PER_SEC / timer;
- }
- void err_check(srtp_err_status_t s)
- {
- if (s == srtp_err_status_ok) {
- return;
- } else {
- fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
- }
- exit(1);
- }
- srtp_err_status_t srtp_test_call_protect(srtp_t srtp_sender,
- srtp_hdr_t *hdr,
- int *len,
- int mki_index)
- {
- if (mki_index == -1) {
- return srtp_protect(srtp_sender, hdr, len);
- } else {
- return srtp_protect_mki(srtp_sender, hdr, len, 1, mki_index);
- }
- }
- srtp_err_status_t srtp_test_call_protect_rtcp(srtp_t srtp_sender,
- srtp_hdr_t *hdr,
- int *len,
- int mki_index)
- {
- if (mki_index == -1) {
- return srtp_protect_rtcp(srtp_sender, hdr, len);
- } else {
- return srtp_protect_rtcp_mki(srtp_sender, hdr, len, 1, mki_index);
- }
- }
- srtp_err_status_t srtp_test_call_unprotect(srtp_t srtp_sender,
- srtp_hdr_t *hdr,
- int *len,
- int use_mki)
- {
- if (use_mki == -1) {
- return srtp_unprotect(srtp_sender, hdr, len);
- } else {
- return srtp_unprotect_mki(srtp_sender, hdr, len, use_mki);
- }
- }
- srtp_err_status_t srtp_test_call_unprotect_rtcp(srtp_t srtp_sender,
- srtp_hdr_t *hdr,
- int *len,
- int use_mki)
- {
- if (use_mki == -1) {
- return srtp_unprotect_rtcp(srtp_sender, hdr, len);
- } else {
- return srtp_unprotect_rtcp_mki(srtp_sender, hdr, len, use_mki);
- }
- }
- srtp_err_status_t srtp_test(const srtp_policy_t *policy,
- int extension_header,
- int mki_index)
- {
- int i;
- srtp_t srtp_sender;
- srtp_t srtp_rcvr;
- srtp_err_status_t status = srtp_err_status_ok;
- srtp_hdr_t *hdr, *hdr2;
- uint8_t hdr_enc[64];
- uint8_t *pkt_end;
- int msg_len_octets, msg_len_enc, msg_len;
- int len, len2;
- uint32_t tag_length;
- uint32_t ssrc;
- srtp_policy_t *rcvr_policy;
- srtp_policy_t tmp_policy;
- int header = 1;
- int use_mki = 0;
- if (mki_index >= 0)
- use_mki = 1;
- if (extension_header) {
- memcpy(&tmp_policy, policy, sizeof(srtp_policy_t));
- tmp_policy.enc_xtn_hdr = &header;
- tmp_policy.enc_xtn_hdr_count = 1;
- err_check(srtp_create(&srtp_sender, &tmp_policy));
- } else {
- err_check(srtp_create(&srtp_sender, policy));
- }
- /* print out policy */
- err_check(srtp_session_print_policy(srtp_sender));
- /*
- * initialize data buffer, using the ssrc in the policy unless that
- * value is a wildcard, in which case we'll just use an arbitrary
- * one
- */
- if (policy->ssrc.type != ssrc_specific) {
- ssrc = 0xdecafbad;
- } else {
- ssrc = policy->ssrc.value;
- }
- msg_len_octets = 28;
- if (extension_header) {
- hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len);
- hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len2);
- } else {
- hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len);
- hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2);
- }
- /* save original msg len */
- msg_len = len;
- if (hdr == NULL) {
- free(hdr2);
- return srtp_err_status_alloc_fail;
- }
- if (hdr2 == NULL) {
- free(hdr);
- return srtp_err_status_alloc_fail;
- }
- debug_print(mod_driver, "before protection:\n%s",
- srtp_packet_to_string(hdr, len));
- #if PRINT_REFERENCE_PACKET
- debug_print(mod_driver, "reference packet before protection:\n%s",
- octet_string_hex_string((uint8_t *)hdr, len));
- #endif
- err_check(srtp_test_call_protect(srtp_sender, hdr, &len, mki_index));
- debug_print(mod_driver, "after protection:\n%s",
- srtp_packet_to_string(hdr, len));
- #if PRINT_REFERENCE_PACKET
- debug_print(mod_driver, "after protection:\n%s",
- octet_string_hex_string((uint8_t *)hdr, len));
- #endif
- /* save protected message and length */
- memcpy(hdr_enc, hdr, len);
- msg_len_enc = len;
- /*
- * check for overrun of the srtp_protect() function
- *
- * The packet is followed by a value of 0xfffff; if the value of the
- * data following the packet is different, then we know that the
- * protect function is overwriting the end of the packet.
- */
- err_check(srtp_get_protect_trailer_length(srtp_sender, use_mki, mki_index,
- &tag_length));
- pkt_end = (uint8_t *)hdr + msg_len + tag_length;
- for (i = 0; i < 4; i++) {
- if (pkt_end[i] != 0xff) {
- fprintf(stdout, "overwrite in srtp_protect() function "
- "(expected %x, found %x in trailing octet %d)\n",
- 0xff, ((uint8_t *)hdr)[i], i);
- free(hdr);
- free(hdr2);
- return srtp_err_status_algo_fail;
- }
- }
- /*
- * if the policy includes confidentiality, check that ciphertext is
- * different than plaintext
- *
- * Note that this check will give false negatives, with some small
- * probability, especially if the packets are short. For that
- * reason, we skip this check if the plaintext is less than four
- * octets long.
- */
- if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
- printf("testing that ciphertext is distinct from plaintext...");
- status = srtp_err_status_algo_fail;
- for (i = 12; i < msg_len_octets + 12; i++) {
- if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
- status = srtp_err_status_ok;
- }
- }
- if (status) {
- printf("failed\n");
- free(hdr);
- free(hdr2);
- return status;
- }
- printf("passed\n");
- }
- /*
- * if the policy uses a 'wildcard' ssrc, then we need to make a copy
- * of the policy that changes the direction to inbound
- *
- * we always copy the policy into the rcvr_policy, since otherwise
- * the compiler would fret about the constness of the policy
- */
- rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
- if (rcvr_policy == NULL) {
- free(hdr);
- free(hdr2);
- return srtp_err_status_alloc_fail;
- }
- if (extension_header) {
- memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t));
- if (tmp_policy.ssrc.type == ssrc_any_outbound) {
- rcvr_policy->ssrc.type = ssrc_any_inbound;
- }
- } else {
- memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
- if (policy->ssrc.type == ssrc_any_outbound) {
- rcvr_policy->ssrc.type = ssrc_any_inbound;
- }
- }
- err_check(srtp_create(&srtp_rcvr, rcvr_policy));
- err_check(srtp_test_call_unprotect(srtp_rcvr, hdr, &len, use_mki));
- debug_print(mod_driver, "after unprotection:\n%s",
- srtp_packet_to_string(hdr, len));
- /* verify that the unprotected packet matches the origial one */
- for (i = 0; i < len; i++) {
- if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
- fprintf(stdout, "mismatch at octet %d\n", i);
- status = srtp_err_status_algo_fail;
- }
- }
- if (status) {
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- }
- /*
- * if the policy includes authentication, then test for false positives
- */
- if (policy->rtp.sec_serv & sec_serv_auth) {
- char *data = ((char *)hdr) + (extension_header ? 24 : 12);
- printf("testing for false positives in replay check...");
- /* unprotect a second time - should fail with a replay error */
- status =
- srtp_test_call_unprotect(srtp_rcvr, hdr, &msg_len_enc, use_mki);
- if (status != srtp_err_status_replay_fail) {
- printf("failed with error code %d\n", status);
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- } else {
- printf("passed\n");
- }
- printf("testing for false positives in auth check...");
- /* increment sequence number in header */
- hdr->seq++;
- /* apply protection */
- err_check(srtp_test_call_protect(srtp_sender, hdr, &len, mki_index));
- /* flip bits in packet */
- data[0] ^= 0xff;
- /* unprotect, and check for authentication failure */
- status = srtp_test_call_unprotect(srtp_rcvr, hdr, &len, use_mki);
- if (status != srtp_err_status_auth_fail) {
- printf("failed\n");
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- } else {
- printf("passed\n");
- }
- }
- err_check(srtp_dealloc(srtp_sender));
- err_check(srtp_dealloc(srtp_rcvr));
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index)
- {
- int i;
- srtp_t srtcp_sender;
- srtp_t srtcp_rcvr;
- srtp_err_status_t status = srtp_err_status_ok;
- srtp_hdr_t *hdr, *hdr2;
- uint8_t hdr_enc[64];
- uint8_t *pkt_end;
- int msg_len_octets, msg_len_enc, msg_len;
- int len, len2;
- uint32_t tag_length;
- uint32_t ssrc;
- srtp_policy_t *rcvr_policy;
- int use_mki = 0;
- if (mki_index >= 0)
- use_mki = 1;
- err_check(srtp_create(&srtcp_sender, policy));
- /* print out policy */
- err_check(srtp_session_print_policy(srtcp_sender));
- /*
- * initialize data buffer, using the ssrc in the policy unless that
- * value is a wildcard, in which case we'll just use an arbitrary
- * one
- */
- if (policy->ssrc.type != ssrc_specific) {
- ssrc = 0xdecafbad;
- } else {
- ssrc = policy->ssrc.value;
- }
- msg_len_octets = 28;
- hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len);
- /* save message len */
- msg_len = len;
- if (hdr == NULL) {
- return srtp_err_status_alloc_fail;
- }
- hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2);
- if (hdr2 == NULL) {
- free(hdr);
- return srtp_err_status_alloc_fail;
- }
- debug_print(mod_driver, "before protection:\n%s",
- srtp_packet_to_string(hdr, len));
- #if PRINT_REFERENCE_PACKET
- debug_print(mod_driver, "reference packet before protection:\n%s",
- octet_string_hex_string((uint8_t *)hdr, len));
- #endif
- err_check(srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index));
- debug_print(mod_driver, "after protection:\n%s",
- srtp_packet_to_string(hdr, len));
- #if PRINT_REFERENCE_PACKET
- debug_print(mod_driver, "after protection:\n%s",
- octet_string_hex_string((uint8_t *)hdr, len));
- #endif
- /* save protected message and length */
- memcpy(hdr_enc, hdr, len);
- msg_len_enc = len;
- /*
- * check for overrun of the srtp_protect() function
- *
- * The packet is followed by a value of 0xfffff; if the value of the
- * data following the packet is different, then we know that the
- * protect function is overwriting the end of the packet.
- */
- srtp_get_protect_rtcp_trailer_length(srtcp_sender, use_mki, mki_index,
- &tag_length);
- pkt_end = (uint8_t *)hdr + msg_len + tag_length;
- for (i = 0; i < 4; i++) {
- if (pkt_end[i] != 0xff) {
- fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
- "(expected %x, found %x in trailing octet %d)\n",
- 0xff, ((uint8_t *)hdr)[i], i);
- free(hdr);
- free(hdr2);
- return srtp_err_status_algo_fail;
- }
- }
- /*
- * if the policy includes confidentiality, check that ciphertext is
- * different than plaintext
- *
- * Note that this check will give false negatives, with some small
- * probability, especially if the packets are short. For that
- * reason, we skip this check if the plaintext is less than four
- * octets long.
- */
- if ((policy->rtcp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
- printf("testing that ciphertext is distinct from plaintext...");
- status = srtp_err_status_algo_fail;
- for (i = 12; i < msg_len_octets + 12; i++) {
- if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
- status = srtp_err_status_ok;
- }
- }
- if (status) {
- printf("failed\n");
- free(hdr);
- free(hdr2);
- return status;
- }
- printf("passed\n");
- }
- /*
- * if the policy uses a 'wildcard' ssrc, then we need to make a copy
- * of the policy that changes the direction to inbound
- *
- * we always copy the policy into the rcvr_policy, since otherwise
- * the compiler would fret about the constness of the policy
- */
- rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
- if (rcvr_policy == NULL) {
- free(hdr);
- free(hdr2);
- return srtp_err_status_alloc_fail;
- }
- memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
- if (policy->ssrc.type == ssrc_any_outbound) {
- rcvr_policy->ssrc.type = ssrc_any_inbound;
- }
- err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
- err_check(srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki));
- debug_print(mod_driver, "after unprotection:\n%s",
- srtp_packet_to_string(hdr, len));
- /* verify that the unprotected packet matches the origial one */
- for (i = 0; i < len; i++) {
- if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
- fprintf(stdout, "mismatch at octet %d\n", i);
- status = srtp_err_status_algo_fail;
- }
- }
- if (status) {
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- }
- /*
- * if the policy includes authentication, then test for false positives
- */
- if (policy->rtp.sec_serv & sec_serv_auth) {
- char *data = ((char *)hdr) + 12;
- printf("testing for false positives in replay check...");
- /* unprotect a second time - should fail with a replay error */
- status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &msg_len_enc,
- use_mki);
- if (status != srtp_err_status_replay_fail) {
- printf("failed with error code %d\n", status);
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- } else {
- printf("passed\n");
- }
- printf("testing for false positives in auth check...");
- /* increment sequence number in header */
- hdr->seq++;
- /* apply protection */
- err_check(
- srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index));
- /* flip bits in packet */
- data[0] ^= 0xff;
- /* unprotect, and check for authentication failure */
- status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki);
- if (status != srtp_err_status_auth_fail) {
- printf("failed\n");
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return status;
- } else {
- printf("passed\n");
- }
- }
- err_check(srtp_dealloc(srtcp_sender));
- err_check(srtp_dealloc(srtcp_rcvr));
- free(hdr);
- free(hdr2);
- free(rcvr_policy);
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_session_print_policy(srtp_t srtp)
- {
- char *serv_descr[4] = { "none", "confidentiality", "authentication",
- "confidentiality and authentication" };
- char *direction[3] = { "unknown", "outbound", "inbound" };
- srtp_stream_t stream;
- srtp_session_keys_t *session_keys = NULL;
- /* sanity checking */
- if (srtp == NULL) {
- return srtp_err_status_fail;
- }
- /* if there's a template stream, print it out */
- if (srtp->stream_template != NULL) {
- stream = srtp->stream_template;
- session_keys = &stream->session_keys[0];
- printf("# SSRC: any %s\r\n"
- "# rtp cipher: %s\r\n"
- "# rtp auth: %s\r\n"
- "# rtp services: %s\r\n"
- "# rtcp cipher: %s\r\n"
- "# rtcp auth: %s\r\n"
- "# rtcp services: %s\r\n"
- "# window size: %lu\r\n"
- "# tx rtx allowed:%s\r\n",
- direction[stream->direction],
- session_keys->rtp_cipher->type->description,
- session_keys->rtp_auth->type->description,
- serv_descr[stream->rtp_services],
- session_keys->rtcp_cipher->type->description,
- session_keys->rtcp_auth->type->description,
- serv_descr[stream->rtcp_services],
- srtp_rdbx_get_window_size(&stream->rtp_rdbx),
- stream->allow_repeat_tx ? "true" : "false");
- printf("# Encrypted extension headers: ");
- if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
- int *enc_xtn_hdr = stream->enc_xtn_hdr;
- int count = stream->enc_xtn_hdr_count;
- while (count > 0) {
- printf("%d ", *enc_xtn_hdr);
- enc_xtn_hdr++;
- count--;
- }
- printf("\n");
- } else {
- printf("none\n");
- }
- }
- /* loop over streams in session, printing the policy of each */
- stream = srtp->stream_list;
- while (stream != NULL) {
- if (stream->rtp_services > sec_serv_conf_and_auth) {
- return srtp_err_status_bad_param;
- }
- session_keys = &stream->session_keys[0];
- printf("# SSRC: 0x%08x\r\n"
- "# rtp cipher: %s\r\n"
- "# rtp auth: %s\r\n"
- "# rtp services: %s\r\n"
- "# rtcp cipher: %s\r\n"
- "# rtcp auth: %s\r\n"
- "# rtcp services: %s\r\n"
- "# window size: %lu\r\n"
- "# tx rtx allowed:%s\r\n",
- stream->ssrc, session_keys->rtp_cipher->type->description,
- session_keys->rtp_auth->type->description,
- serv_descr[stream->rtp_services],
- session_keys->rtcp_cipher->type->description,
- session_keys->rtcp_auth->type->description,
- serv_descr[stream->rtcp_services],
- srtp_rdbx_get_window_size(&stream->rtp_rdbx),
- stream->allow_repeat_tx ? "true" : "false");
- printf("# Encrypted extension headers: ");
- if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
- int *enc_xtn_hdr = stream->enc_xtn_hdr;
- int count = stream->enc_xtn_hdr_count;
- while (count > 0) {
- printf("%d ", *enc_xtn_hdr);
- enc_xtn_hdr++;
- count--;
- }
- printf("\n");
- } else {
- printf("none\n");
- }
- /* advance to next stream in the list */
- stream = stream->next;
- }
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_print_policy(const srtp_policy_t *policy)
- {
- srtp_err_status_t status;
- srtp_t session;
- status = srtp_create(&session, policy);
- if (status) {
- return status;
- }
- status = srtp_session_print_policy(session);
- if (status) {
- return status;
- }
- status = srtp_dealloc(session);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- /*
- * srtp_print_packet(...) is for debugging only
- * it prints an RTP packet to the stdout
- *
- * note that this function is *not* threadsafe
- */
- #include <stdio.h>
- #define MTU 2048
- char packet_string[MTU];
- char *srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len)
- {
- int octets_in_rtp_header = 12;
- uint8_t *data = ((uint8_t *)hdr) + octets_in_rtp_header;
- int hex_len = pkt_octet_len - octets_in_rtp_header;
- /* sanity checking */
- if ((hdr == NULL) || (pkt_octet_len > MTU)) {
- return NULL;
- }
- /* write packet into string */
- sprintf(packet_string, "(s)rtp packet: {\n"
- " version:\t%d\n"
- " p:\t\t%d\n"
- " x:\t\t%d\n"
- " cc:\t\t%d\n"
- " m:\t\t%d\n"
- " pt:\t\t%x\n"
- " seq:\t\t%x\n"
- " ts:\t\t%x\n"
- " ssrc:\t%x\n"
- " data:\t%s\n"
- "} (%d octets in total)\n",
- hdr->version, hdr->p, hdr->x, hdr->cc, hdr->m, hdr->pt, hdr->seq,
- hdr->ts, hdr->ssrc, octet_string_hex_string(data, hex_len),
- pkt_octet_len);
- return packet_string;
- }
- /*
- * mips_estimate() is a simple function to estimate the number of
- * instructions per second that the host can perform. note that this
- * function can be grossly wrong; you may want to have a manual sanity
- * check of its output!
- *
- * the 'ignore' pointer is there to convince the compiler to not just
- * optimize away the function
- */
- double mips_estimate(int num_trials, int *ignore)
- {
- clock_t t;
- volatile int i, sum;
- sum = 0;
- t = clock();
- for (i = 0; i < num_trials; i++) {
- sum += i;
- }
- t = clock() - t;
- if (t < 1) {
- t = 1;
- }
- /* printf("%d\n", sum); */
- *ignore = sum;
- return (double)num_trials * CLOCKS_PER_SEC / t;
- }
- /*
- * srtp_validate() verifies the correctness of libsrtp by comparing
- * some computed packets against some pre-computed reference values.
- * These packets were made with the default SRTP policy.
- */
- srtp_err_status_t srtp_validate()
- {
- // clang-format off
- uint8_t srtp_plaintext_ref[28] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab
- };
- uint8_t srtp_plaintext[38] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtp_ciphertext[38] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
- 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
- 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
- 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
- };
- uint8_t rtcp_plaintext_ref[24] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- };
- uint8_t rtcp_plaintext[38] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtcp_ciphertext[38] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0x71, 0x28, 0x03, 0x5b, 0xe4, 0x87, 0xb9, 0xbd,
- 0xbe, 0xf8, 0x90, 0x41, 0xf9, 0x77, 0xa5, 0xa8,
- 0x80, 0x00, 0x00, 0x01, 0x99, 0x3e, 0x08, 0xcd,
- 0x54, 0xd6, 0xc1, 0x23, 0x07, 0x98
- };
- // clang-format on
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status) {
- return status;
- }
- /*
- * protect plaintext, then compare with ciphertext
- */
- len = 28;
- status = srtp_protect(srtp_snd, srtp_plaintext, &len);
- if (status || (len != 38)) {
- return srtp_err_status_fail;
- }
- debug_print(mod_driver, "ciphertext:\n %s",
- octet_string_hex_string(srtp_plaintext, len));
- debug_print(mod_driver, "ciphertext reference:\n %s",
- octet_string_hex_string(srtp_ciphertext, len));
- if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
- return srtp_err_status_fail;
- }
- /*
- * protect plaintext rtcp, then compare with srtcp ciphertext
- */
- len = 24;
- status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
- if (status || (len != 38)) {
- return srtp_err_status_fail;
- }
- debug_print(mod_driver, "srtcp ciphertext:\n %s",
- octet_string_hex_string(rtcp_plaintext, len));
- debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
- octet_string_hex_string(srtcp_ciphertext, len));
- if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
- return srtp_err_status_fail;
- }
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status) {
- return status;
- }
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status || (len != 28)) {
- return status;
- }
- if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
- return srtp_err_status_fail;
- }
- /*
- * unprotect srtcp ciphertext, then compare with rtcp plaintext
- */
- len = 38;
- status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
- if (status || (len != 24)) {
- return status;
- }
- if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(srtp_snd);
- if (status) {
- return status;
- }
- status = srtp_dealloc(srtp_recv);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- #ifdef GCM
- /*
- * srtp_validate_gcm() verifies the correctness of libsrtp by comparing
- * an computed packet against the known ciphertext for the plaintext.
- */
- srtp_err_status_t srtp_validate_gcm()
- {
- // clang-format off
- unsigned char test_key_gcm[28] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab
- };
- uint8_t rtp_plaintext_ref[28] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab
- };
- uint8_t rtp_plaintext[44] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtp_ciphertext[44] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde,
- 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0,
- 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26,
- 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1,
- 0x27, 0xe8, 0xa3, 0x92
- };
- uint8_t rtcp_plaintext_ref[24] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- };
- uint8_t rtcp_plaintext[44] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtcp_ciphertext[44] = {
- 0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
- 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55,
- 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25,
- 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46,
- 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e,
- 0x80, 0x00, 0x00, 0x01
- };
- // clang-format on
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key_gcm;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status) {
- return status;
- }
- /*
- * protect plaintext rtp, then compare with srtp ciphertext
- */
- len = 28;
- status = srtp_protect(srtp_snd, rtp_plaintext, &len);
- if (status || (len != 44)) {
- return srtp_err_status_fail;
- }
- debug_print(mod_driver, "srtp ciphertext:\n %s",
- octet_string_hex_string(rtp_plaintext, len));
- debug_print(mod_driver, "srtp ciphertext reference:\n %s",
- octet_string_hex_string(srtp_ciphertext, len));
- if (srtp_octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
- return srtp_err_status_fail;
- }
- /*
- * protect plaintext rtcp, then compare with srtcp ciphertext
- */
- len = 24;
- status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
- if (status || (len != 44)) {
- return srtp_err_status_fail;
- }
- debug_print(mod_driver, "srtcp ciphertext:\n %s",
- octet_string_hex_string(rtcp_plaintext, len));
- debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
- octet_string_hex_string(srtcp_ciphertext, len));
- if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
- return srtp_err_status_fail;
- }
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status) {
- return status;
- }
- /*
- * unprotect srtp ciphertext, then compare with rtp plaintext
- */
- len = 44;
- status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status || (len != 28)) {
- return status;
- }
- if (srtp_octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
- return srtp_err_status_fail;
- }
- /*
- * unprotect srtcp ciphertext, then compare with rtcp plaintext
- */
- len = 44;
- status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
- if (status || (len != 24)) {
- return status;
- }
- if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(srtp_snd);
- if (status) {
- return status;
- }
- status = srtp_dealloc(srtp_recv);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- #endif
- /*
- * Test vectors taken from RFC 6904, Appendix A
- */
- srtp_err_status_t srtp_validate_encrypted_extensions_headers()
- {
- // clang-format off
- unsigned char test_key_ext_headers[30] = {
- 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
- 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
- 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
- uint8_t srtp_plaintext_ref[56] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
- 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
- 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
- };
- uint8_t srtp_plaintext[66] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
- 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
- 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- };
- uint8_t srtp_ciphertext[66] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
- 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
- 0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
- 0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8,
- 0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02,
- 0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8,
- 0x91, 0xc7
- };
- // clang-format on
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- int headers[3] = { 1, 3, 4 };
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key_ext_headers;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.enc_xtn_hdr = headers;
- policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status)
- return status;
- /*
- * protect plaintext, then compare with ciphertext
- */
- len = sizeof(srtp_plaintext_ref);
- status = srtp_protect(srtp_snd, srtp_plaintext, &len);
- if (status || (len != sizeof(srtp_plaintext)))
- return srtp_err_status_fail;
- debug_print(mod_driver, "ciphertext:\n %s",
- srtp_octet_string_hex_string(srtp_plaintext, len));
- debug_print(mod_driver, "ciphertext reference:\n %s",
- srtp_octet_string_hex_string(srtp_ciphertext, len));
- if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
- return srtp_err_status_fail;
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status)
- return status;
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status) {
- return status;
- } else if (len != sizeof(srtp_plaintext_ref)) {
- return srtp_err_status_fail;
- }
- if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
- return srtp_err_status_fail;
- status = srtp_dealloc(srtp_snd);
- if (status)
- return status;
- status = srtp_dealloc(srtp_recv);
- if (status)
- return status;
- return srtp_err_status_ok;
- }
- #ifdef GCM
- /*
- * Headers of test vectors taken from RFC 6904, Appendix A
- */
- srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm()
- {
- // clang-format off
- unsigned char test_key_ext_headers[30] = {
- 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
- 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
- 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
- uint8_t srtp_plaintext_ref[56] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
- 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
- 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
- };
- uint8_t srtp_plaintext[64] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
- 0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
- 0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtp_ciphertext[64] = {
- 0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
- 0x17, 0x12, 0xe0, 0x20, 0x5b, 0xfa, 0x94, 0x9b,
- 0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0xbb, 0x46,
- 0x73, 0x27, 0x78, 0xd9, 0x92, 0x9a, 0xab, 0x00,
- 0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
- 0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
- 0xf4, 0xb1, 0xb7, 0x59, 0x71, 0x9e, 0xb5, 0xbc
- };
- // clang-format on
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- int headers[3] = { 1, 3, 4 };
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
- srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key_ext_headers;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.enc_xtn_hdr = headers;
- policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status)
- return status;
- /*
- * protect plaintext, then compare with ciphertext
- */
- len = sizeof(srtp_plaintext_ref);
- status = srtp_protect(srtp_snd, srtp_plaintext, &len);
- if (status || (len != sizeof(srtp_plaintext)))
- return srtp_err_status_fail;
- debug_print(mod_driver, "ciphertext:\n %s",
- srtp_octet_string_hex_string(srtp_plaintext, len));
- debug_print(mod_driver, "ciphertext reference:\n %s",
- srtp_octet_string_hex_string(srtp_ciphertext, len));
- if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
- return srtp_err_status_fail;
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status)
- return status;
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status) {
- return status;
- } else if (len != sizeof(srtp_plaintext_ref)) {
- return srtp_err_status_fail;
- }
- if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
- return srtp_err_status_fail;
- status = srtp_dealloc(srtp_snd);
- if (status)
- return status;
- status = srtp_dealloc(srtp_recv);
- if (status)
- return status;
- return srtp_err_status_ok;
- }
- #endif
- /*
- * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
- * some computed packets against some pre-computed reference values.
- * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
- */
- srtp_err_status_t srtp_validate_aes_256()
- {
- // clang-format off
- unsigned char aes_256_test_key[46] = {
- 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
- 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
- 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
- 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
- 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
- 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
- };
- uint8_t srtp_plaintext_ref[28] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab
- };
- uint8_t srtp_plaintext[38] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- uint8_t srtp_ciphertext[38] = {
- 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
- 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
- 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
- 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
- 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
- };
- // clang-format on
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
- srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = aes_256_test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status) {
- return status;
- }
- /*
- * protect plaintext, then compare with ciphertext
- */
- len = 28;
- status = srtp_protect(srtp_snd, srtp_plaintext, &len);
- if (status || (len != 38)) {
- return srtp_err_status_fail;
- }
- debug_print(mod_driver, "ciphertext:\n %s",
- octet_string_hex_string(srtp_plaintext, len));
- debug_print(mod_driver, "ciphertext reference:\n %s",
- octet_string_hex_string(srtp_ciphertext, len));
- if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
- return srtp_err_status_fail;
- }
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status) {
- return status;
- }
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status || (len != 28)) {
- return status;
- }
- if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(srtp_snd);
- if (status) {
- return status;
- }
- status = srtp_dealloc(srtp_recv);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list)
- {
- extern const srtp_policy_t *policy_array[];
- srtp_policy_t *p, *tmp;
- int i = 0;
- uint32_t ssrc = 0;
- /* sanity checking */
- if ((list == NULL) || (policy_array[0] == NULL)) {
- return srtp_err_status_bad_param;
- }
- /*
- * loop over policy list, mallocing a new list and copying values
- * into it (and incrementing the SSRC value as we go along)
- */
- tmp = NULL;
- while (policy_array[i] != NULL) {
- p = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
- if (p == NULL) {
- return srtp_err_status_bad_param;
- }
- memcpy(p, policy_array[i], sizeof(srtp_policy_t));
- p->ssrc.type = ssrc_specific;
- p->ssrc.value = ssrc++;
- p->next = tmp;
- tmp = p;
- i++;
- }
- *list = p;
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list)
- {
- srtp_policy_t *p, *next;
- for (p = list; p != NULL; p = next) {
- next = p->next;
- free(p);
- }
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_empty_payload()
- {
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- srtp_hdr_t *mesg;
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status) {
- return status;
- }
- mesg = srtp_create_test_packet(0, policy.ssrc.value, &len);
- if (mesg == NULL) {
- return srtp_err_status_fail;
- }
- status = srtp_protect(srtp_snd, mesg, &len);
- if (status) {
- return status;
- } else if (len != 12 + 10) {
- return srtp_err_status_fail;
- }
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status) {
- return status;
- }
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, mesg, &len);
- if (status) {
- return status;
- } else if (len != 12) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(srtp_snd);
- if (status) {
- return status;
- }
- status = srtp_dealloc(srtp_recv);
- if (status) {
- return status;
- }
- free(mesg);
- return srtp_err_status_ok;
- }
- #ifdef GCM
- srtp_err_status_t srtp_test_empty_payload_gcm()
- {
- srtp_t srtp_snd, srtp_recv;
- srtp_err_status_t status;
- int len;
- srtp_policy_t policy;
- srtp_hdr_t *mesg;
- /*
- * create a session with a single stream using the default srtp
- * policy and with the SSRC value 0xcafebabe
- */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
- srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&srtp_snd, &policy);
- if (status) {
- return status;
- }
- mesg = srtp_create_test_packet(0, policy.ssrc.value, &len);
- if (mesg == NULL) {
- return srtp_err_status_fail;
- }
- status = srtp_protect(srtp_snd, mesg, &len);
- if (status) {
- return status;
- } else if (len != 12 + 8) {
- return srtp_err_status_fail;
- }
- /*
- * create a receiver session context comparable to the one created
- * above - we need to do this so that the replay checking doesn't
- * complain
- */
- status = srtp_create(&srtp_recv, &policy);
- if (status) {
- return status;
- }
- /*
- * unprotect ciphertext, then compare with plaintext
- */
- status = srtp_unprotect(srtp_recv, mesg, &len);
- if (status) {
- return status;
- } else if (len != 12) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(srtp_snd);
- if (status) {
- return status;
- }
- status = srtp_dealloc(srtp_recv);
- if (status) {
- return status;
- }
- free(mesg);
- return srtp_err_status_ok;
- }
- #endif // GCM
- srtp_err_status_t srtp_test_remove_stream()
- {
- srtp_err_status_t status;
- srtp_policy_t *policy_list, policy;
- srtp_t session;
- srtp_stream_t stream;
- /*
- * srtp_get_stream() is a libSRTP internal function that we declare
- * here so that we can use it to verify the correct operation of the
- * library
- */
- extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
- status = srtp_create_big_policy(&policy_list);
- if (status) {
- return status;
- }
- status = srtp_create(&session, policy_list);
- if (status) {
- return status;
- }
- /*
- * check for false positives by trying to remove a stream that's not
- * in the session
- */
- status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
- if (status != srtp_err_status_no_ctx) {
- return srtp_err_status_fail;
- }
- /*
- * check for false negatives by removing stream 0x1, then
- * searching for streams 0x0 and 0x2
- */
- status = srtp_remove_stream(session, htonl(0x1));
- if (status != srtp_err_status_ok) {
- return srtp_err_status_fail;
- }
- stream = srtp_get_stream(session, htonl(0x0));
- if (stream == NULL) {
- return srtp_err_status_fail;
- }
- stream = srtp_get_stream(session, htonl(0x2));
- if (stream == NULL) {
- return srtp_err_status_fail;
- }
- status = srtp_dealloc(session);
- if (status != srtp_err_status_ok) {
- return status;
- }
- status = srtp_dealloc_big_policy(policy_list);
- if (status != srtp_err_status_ok) {
- return status;
- }
- /* Now test adding and removing a single stream */
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key;
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- status = srtp_create(&session, NULL);
- if (status != srtp_err_status_ok) {
- return status;
- }
- status = srtp_add_stream(session, &policy);
- if (status != srtp_err_status_ok) {
- return status;
- }
- status = srtp_remove_stream(session, htonl(0xcafebabe));
- if (status != srtp_err_status_ok) {
- return status;
- }
- status = srtp_dealloc(session);
- if (status != srtp_err_status_ok) {
- return status;
- }
- return srtp_err_status_ok;
- }
- // clang-format off
- unsigned char test_alt_key[46] = {
- 0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
- 0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
- 0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
- 0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
- 0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
- // clang-format on
- /*
- * srtp_test_update() verifies updating/rekeying exsisting streams.
- * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
- * the value of the ROC must not be reset after a rekey, this test
- * atempts to prove that srtp_update does not reset the ROC.
- */
- srtp_err_status_t srtp_test_update()
- {
- srtp_err_status_t status;
- uint32_t ssrc = 0x12121212;
- int msg_len_octets = 32;
- int protected_msg_len_octets;
- srtp_hdr_t *msg;
- srtp_t srtp_snd, srtp_recv;
- srtp_policy_t policy;
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- policy.ssrc.type = ssrc_any_outbound;
- policy.key = test_key;
- /* create a send and recive ctx with defualt profile and test_key */
- status = srtp_create(&srtp_recv, &policy);
- if (status)
- return status;
- policy.ssrc.type = ssrc_any_inbound;
- status = srtp_create(&srtp_snd, &policy);
- if (status)
- return status;
- /* protect and unprotect two msg's that will cause the ROC to be equal to 1
- */
- msg = srtp_create_test_packet(msg_len_octets, ssrc,
- &protected_msg_len_octets);
- if (msg == NULL)
- return srtp_err_status_alloc_fail;
- msg->seq = htons(65535);
- status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
- if (status)
- return srtp_err_status_fail;
- status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
- if (status)
- return status;
- free(msg);
- msg = srtp_create_test_packet(msg_len_octets, ssrc,
- &protected_msg_len_octets);
- if (msg == NULL)
- return srtp_err_status_alloc_fail;
- msg->seq = htons(1);
- status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
- if (status)
- return srtp_err_status_fail;
- status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
- if (status)
- return status;
- free(msg);
- /* update send ctx with same test_key t verify update works*/
- policy.ssrc.type = ssrc_any_outbound;
- policy.key = test_key;
- status = srtp_update(srtp_snd, &policy);
- if (status)
- return status;
- msg = srtp_create_test_packet(msg_len_octets, ssrc,
- &protected_msg_len_octets);
- if (msg == NULL)
- return srtp_err_status_alloc_fail;
- msg->seq = htons(2);
- status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
- if (status)
- return srtp_err_status_fail;
- status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
- if (status)
- return status;
- free(msg);
- /* update send ctx to use test_alt_key */
- policy.ssrc.type = ssrc_any_outbound;
- policy.key = test_alt_key;
- status = srtp_update(srtp_snd, &policy);
- if (status)
- return status;
- /* create and protect msg with new key and ROC still equal to 1 */
- msg = srtp_create_test_packet(msg_len_octets, ssrc,
- &protected_msg_len_octets);
- if (msg == NULL)
- return srtp_err_status_alloc_fail;
- msg->seq = htons(3);
- status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
- if (status)
- return srtp_err_status_fail;
- /* verify that recive ctx will fail to unprotect as it still uses test_key
- */
- status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
- if (status == srtp_err_status_ok)
- return srtp_err_status_fail;
- /* create a new recvieve ctx with test_alt_key but since it is new it will
- * have ROC equal to 1
- * and therefore should fail to unprotected */
- {
- srtp_t srtp_recv_roc_0;
- policy.ssrc.type = ssrc_any_inbound;
- policy.key = test_alt_key;
- status = srtp_create(&srtp_recv_roc_0, &policy);
- if (status)
- return status;
- status =
- srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
- if (status == srtp_err_status_ok)
- return srtp_err_status_fail;
- status = srtp_dealloc(srtp_recv_roc_0);
- if (status)
- return status;
- }
- /* update recive ctx to use test_alt_key */
- policy.ssrc.type = ssrc_any_inbound;
- policy.key = test_alt_key;
- status = srtp_update(srtp_recv, &policy);
- if (status)
- return status;
- /* verify that can still unprotect, therfore key is updated and ROC value is
- * preserved */
- status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
- if (status)
- return status;
- free(msg);
- status = srtp_dealloc(srtp_snd);
- if (status)
- return status;
- status = srtp_dealloc(srtp_recv);
- if (status)
- return status;
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_setup_protect_trailer_streams(
- srtp_t *srtp_send,
- srtp_t *srtp_send_mki,
- srtp_t *srtp_send_aes_gcm,
- srtp_t *srtp_send_aes_gcm_mki)
- {
- srtp_err_status_t status;
- srtp_policy_t policy;
- srtp_policy_t policy_mki;
- #ifdef GCM
- srtp_policy_t policy_aes_gcm;
- srtp_policy_t policy_aes_gcm_mki;
- #endif // GCM
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ekt = NULL;
- policy.window_size = 128;
- policy.allow_repeat_tx = 0;
- policy.next = NULL;
- policy.ssrc.type = ssrc_any_outbound;
- policy.key = test_key;
- memset(&policy_mki, 0, sizeof(policy_mki));
- srtp_crypto_policy_set_rtp_default(&policy_mki.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy_mki.rtcp);
- policy_mki.ekt = NULL;
- policy_mki.window_size = 128;
- policy_mki.allow_repeat_tx = 0;
- policy_mki.next = NULL;
- policy_mki.ssrc.type = ssrc_any_outbound;
- policy_mki.key = NULL;
- policy_mki.keys = test_keys;
- policy_mki.num_master_keys = 2;
- #ifdef GCM
- memset(&policy_aes_gcm, 0, sizeof(policy_aes_gcm));
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtp);
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtcp);
- policy_aes_gcm.ekt = NULL;
- policy_aes_gcm.window_size = 128;
- policy_aes_gcm.allow_repeat_tx = 0;
- policy_aes_gcm.next = NULL;
- policy_aes_gcm.ssrc.type = ssrc_any_outbound;
- policy_aes_gcm.key = test_key;
- memset(&policy_aes_gcm_mki, 0, sizeof(policy_aes_gcm_mki));
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm_mki.rtp);
- srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm_mki.rtcp);
- policy_aes_gcm_mki.ekt = NULL;
- policy_aes_gcm_mki.window_size = 128;
- policy_aes_gcm_mki.allow_repeat_tx = 0;
- policy_aes_gcm_mki.next = NULL;
- policy_aes_gcm_mki.ssrc.type = ssrc_any_outbound;
- policy_aes_gcm_mki.key = NULL;
- policy_aes_gcm_mki.keys = test_keys;
- policy_aes_gcm_mki.num_master_keys = 2;
- #endif // GCM
- /* create a send ctx with defualt profile and test_key */
- status = srtp_create(srtp_send, &policy);
- if (status)
- return status;
- status = srtp_create(srtp_send_mki, &policy_mki);
- if (status)
- return status;
- #ifdef GCM
- status = srtp_create(srtp_send_aes_gcm, &policy_aes_gcm);
- if (status)
- return status;
- status = srtp_create(srtp_send_aes_gcm_mki, &policy_aes_gcm_mki);
- if (status)
- return status;
- #endif // GCM
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_protect_trailer_length()
- {
- srtp_t srtp_send;
- srtp_t srtp_send_mki;
- srtp_t srtp_send_aes_gcm;
- srtp_t srtp_send_aes_gcm_mki;
- uint32_t length = 0;
- srtp_err_status_t status;
- srtp_test_setup_protect_trailer_streams(
- &srtp_send, &srtp_send_mki, &srtp_send_aes_gcm, &srtp_send_aes_gcm_mki);
- status = srtp_get_protect_trailer_length(srtp_send, 0, 0, &length);
- if (status)
- return status;
- /* TAG Length: 10 bytes */
- if (length != 10)
- return srtp_err_status_fail;
- status = srtp_get_protect_trailer_length(srtp_send_mki, 1, 1, &length);
- if (status)
- return status;
- /* TAG Length: 10 bytes + MKI length: 4 bytes*/
- if (length != 14)
- return srtp_err_status_fail;
- #ifdef GCM
- status = srtp_get_protect_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
- if (status)
- return status;
- /* TAG Length: 16 bytes */
- if (length != 16)
- return srtp_err_status_fail;
- status =
- srtp_get_protect_trailer_length(srtp_send_aes_gcm_mki, 1, 1, &length);
- if (status)
- return status;
- /* TAG Length: 16 bytes + MKI length: 4 bytes*/
- if (length != 20)
- return srtp_err_status_fail;
- #endif // GCM
- srtp_dealloc(srtp_send);
- srtp_dealloc(srtp_send_mki);
- #ifdef GCM
- srtp_dealloc(srtp_send_aes_gcm);
- srtp_dealloc(srtp_send_aes_gcm_mki);
- #endif
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_protect_rtcp_trailer_length()
- {
- srtp_t srtp_send;
- srtp_t srtp_send_mki;
- srtp_t srtp_send_aes_gcm;
- srtp_t srtp_send_aes_gcm_mki;
- uint32_t length = 0;
- srtp_err_status_t status;
- srtp_test_setup_protect_trailer_streams(
- &srtp_send, &srtp_send_mki, &srtp_send_aes_gcm, &srtp_send_aes_gcm_mki);
- status = srtp_get_protect_rtcp_trailer_length(srtp_send, 0, 0, &length);
- if (status)
- return status;
- /* TAG Length: 10 bytes + SRTCP Trailer 4 bytes*/
- if (length != 14)
- return srtp_err_status_fail;
- status = srtp_get_protect_rtcp_trailer_length(srtp_send_mki, 1, 1, &length);
- if (status)
- return status;
- /* TAG Length: 10 bytes + SRTCP Trailer 4 bytes + MKI 4 bytes*/
- if (length != 18)
- return srtp_err_status_fail;
- #ifdef GCM
- status =
- srtp_get_protect_rtcp_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
- if (status)
- return status;
- /* TAG Length: 16 bytes + SRTCP Trailer 4 bytes*/
- if (length != 20)
- return srtp_err_status_fail;
- status = srtp_get_protect_rtcp_trailer_length(srtp_send_aes_gcm_mki, 1, 1,
- &length);
- if (status)
- return status;
- /* TAG Length: 16 bytes + SRTCP Trailer 4 bytes + MKI 4 bytes*/
- if (length != 24)
- return srtp_err_status_fail;
- #endif // GCM
- srtp_dealloc(srtp_send);
- srtp_dealloc(srtp_send_mki);
- #ifdef GCM
- srtp_dealloc(srtp_send_aes_gcm);
- srtp_dealloc(srtp_send_aes_gcm_mki);
- #endif
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_get_roc()
- {
- srtp_err_status_t status;
- srtp_policy_t policy;
- srtp_t session;
- srtp_hdr_t *pkt;
- uint32_t i;
- uint32_t roc;
- uint32_t ts;
- uint16_t seq;
- int msg_len_octets = 32;
- int protected_msg_len_octets;
- memset(&policy, 0, sizeof(policy));
- srtp_crypto_policy_set_rtp_default(&policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
- policy.ssrc.type = ssrc_specific;
- policy.ssrc.value = 0xcafebabe;
- policy.key = test_key;
- policy.window_size = 128;
- /* Create a sender session */
- status = srtp_create(&session, &policy);
- if (status) {
- return status;
- }
- /* Set start sequence so we roll over */
- seq = 65535;
- ts = 0;
- for (i = 0; i < 2; i++) {
- pkt = srtp_create_test_packet_extended(msg_len_octets,
- policy.ssrc.value, seq, ts,
- &protected_msg_len_octets);
- status = srtp_protect(session, pkt, &protected_msg_len_octets);
- free(pkt);
- if (status) {
- return status;
- }
- status = srtp_get_stream_roc(session, policy.ssrc.value, &roc);
- if (status) {
- return status;
- }
- if (roc != i) {
- return srtp_err_status_fail;
- }
- seq++;
- ts++;
- }
- /* Cleanup */
- status = srtp_dealloc(session);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- static srtp_err_status_t test_set_receiver_roc(uint32_t packets,
- uint32_t roc_to_set)
- {
- srtp_err_status_t status;
- srtp_policy_t sender_policy;
- srtp_t sender_session;
- srtp_policy_t receiver_policy;
- srtp_t receiver_session;
- srtp_hdr_t *pkt_1;
- unsigned char *recv_pkt_1;
- srtp_hdr_t *pkt_2;
- unsigned char *recv_pkt_2;
- uint32_t i;
- uint32_t ts;
- uint16_t seq;
- int msg_len_octets = 32;
- int protected_msg_len_octets_1;
- int protected_msg_len_octets_2;
- /* Create sender */
- memset(&sender_policy, 0, sizeof(sender_policy));
- srtp_crypto_policy_set_rtp_default(&sender_policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&sender_policy.rtcp);
- sender_policy.ssrc.type = ssrc_specific;
- sender_policy.ssrc.value = 0xcafebabe;
- sender_policy.key = test_key;
- sender_policy.window_size = 128;
- status = srtp_create(&sender_session, &sender_policy);
- if (status) {
- return status;
- }
- /* Create and protect packets */
- seq = 0;
- ts = 0;
- for (i = 0; i < packets; i++) {
- srtp_hdr_t *tmp_pkt;
- int tmp_len;
- tmp_pkt = srtp_create_test_packet_extended(
- msg_len_octets, sender_policy.ssrc.value, seq, ts, &tmp_len);
- status = srtp_protect(sender_session, tmp_pkt, &tmp_len);
- free(tmp_pkt);
- if (status) {
- return status;
- }
- seq++;
- ts++;
- }
- /* Create the first packet to decrypt and test for ROC change */
- pkt_1 = srtp_create_test_packet_extended(msg_len_octets,
- sender_policy.ssrc.value, seq, ts,
- &protected_msg_len_octets_1);
- status = srtp_protect(sender_session, pkt_1, &protected_msg_len_octets_1);
- if (status) {
- return status;
- }
- /* Create the second packet to decrypt and test for ROC change */
- seq++;
- ts++;
- pkt_2 = srtp_create_test_packet_extended(msg_len_octets,
- sender_policy.ssrc.value, seq, ts,
- &protected_msg_len_octets_2);
- status = srtp_protect(sender_session, pkt_2, &protected_msg_len_octets_2);
- if (status) {
- return status;
- }
- /* Create the receiver */
- memset(&receiver_policy, 0, sizeof(receiver_policy));
- srtp_crypto_policy_set_rtp_default(&receiver_policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&receiver_policy.rtcp);
- receiver_policy.ssrc.type = ssrc_specific;
- receiver_policy.ssrc.value = sender_policy.ssrc.value;
- receiver_policy.key = test_key;
- receiver_policy.window_size = 128;
- status = srtp_create(&receiver_session, &receiver_policy);
- if (status) {
- return status;
- }
- /* Make a copy of the first sent protected packet */
- recv_pkt_1 = malloc(protected_msg_len_octets_1);
- if (recv_pkt_1 == NULL) {
- return srtp_err_status_fail;
- }
- memcpy(recv_pkt_1, pkt_1, protected_msg_len_octets_1);
- /* Make a copy of the second sent protected packet */
- recv_pkt_2 = malloc(protected_msg_len_octets_2);
- if (recv_pkt_2 == NULL) {
- return srtp_err_status_fail;
- }
- memcpy(recv_pkt_2, pkt_2, protected_msg_len_octets_2);
- /* Set the ROC to the wanted value */
- status = srtp_set_stream_roc(receiver_session, receiver_policy.ssrc.value,
- roc_to_set);
- if (status) {
- return status;
- }
- /* Unprotect the first packet */
- status = srtp_unprotect(receiver_session, recv_pkt_1,
- &protected_msg_len_octets_1);
- if (status) {
- return status;
- }
- /* Unprotect the second packet */
- status = srtp_unprotect(receiver_session, recv_pkt_2,
- &protected_msg_len_octets_2);
- if (status) {
- return status;
- }
- /* Cleanup */
- status = srtp_dealloc(sender_session);
- if (status) {
- return status;
- }
- status = srtp_dealloc(receiver_session);
- if (status) {
- return status;
- }
- free(pkt_1);
- free(recv_pkt_1);
- free(pkt_2);
- free(recv_pkt_2);
- return srtp_err_status_ok;
- }
- static srtp_err_status_t test_set_sender_roc(uint16_t seq, uint32_t roc_to_set)
- {
- srtp_err_status_t status;
- srtp_policy_t sender_policy;
- srtp_t sender_session;
- srtp_policy_t receiver_policy;
- srtp_t receiver_session;
- srtp_hdr_t *pkt;
- unsigned char *recv_pkt;
- uint32_t ts;
- int msg_len_octets = 32;
- int protected_msg_len_octets;
- /* Create sender */
- memset(&sender_policy, 0, sizeof(sender_policy));
- srtp_crypto_policy_set_rtp_default(&sender_policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&sender_policy.rtcp);
- sender_policy.ssrc.type = ssrc_specific;
- sender_policy.ssrc.value = 0xcafebabe;
- sender_policy.key = test_key;
- sender_policy.window_size = 128;
- status = srtp_create(&sender_session, &sender_policy);
- if (status) {
- return status;
- }
- /* Set the ROC before encrypting the first packet */
- status = srtp_set_stream_roc(sender_session, sender_policy.ssrc.value,
- roc_to_set);
- if (status != srtp_err_status_ok) {
- return status;
- }
- /* Create the packet to decrypt */
- ts = 0;
- pkt = srtp_create_test_packet_extended(msg_len_octets,
- sender_policy.ssrc.value, seq, ts,
- &protected_msg_len_octets);
- status = srtp_protect(sender_session, pkt, &protected_msg_len_octets);
- if (status) {
- return status;
- }
- /* Create the receiver */
- memset(&receiver_policy, 0, sizeof(receiver_policy));
- srtp_crypto_policy_set_rtp_default(&receiver_policy.rtp);
- srtp_crypto_policy_set_rtcp_default(&receiver_policy.rtcp);
- receiver_policy.ssrc.type = ssrc_specific;
- receiver_policy.ssrc.value = sender_policy.ssrc.value;
- receiver_policy.key = test_key;
- receiver_policy.window_size = 128;
- status = srtp_create(&receiver_session, &receiver_policy);
- if (status) {
- return status;
- }
- /* Make a copy of the sent protected packet */
- recv_pkt = malloc(protected_msg_len_octets);
- if (recv_pkt == NULL) {
- return srtp_err_status_fail;
- }
- memcpy(recv_pkt, pkt, protected_msg_len_octets);
- /* Set the ROC to the wanted value */
- status = srtp_set_stream_roc(receiver_session, receiver_policy.ssrc.value,
- roc_to_set);
- if (status) {
- return status;
- }
- status =
- srtp_unprotect(receiver_session, recv_pkt, &protected_msg_len_octets);
- if (status) {
- return status;
- }
- /* Cleanup */
- status = srtp_dealloc(sender_session);
- if (status) {
- return status;
- }
- status = srtp_dealloc(receiver_session);
- if (status) {
- return status;
- }
- free(pkt);
- free(recv_pkt);
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_set_receiver_roc()
- {
- int packets;
- uint32_t roc;
- srtp_err_status_t status;
- /* First test does not rollover */
- packets = 1;
- roc = 0;
- status = test_set_receiver_roc(packets - 1, roc);
- if (status) {
- return status;
- }
- status = test_set_receiver_roc(packets, roc);
- if (status) {
- return status;
- }
- status = test_set_receiver_roc(packets + 1, roc);
- if (status) {
- return status;
- }
- status = test_set_receiver_roc(packets + 60000, roc);
- if (status) {
- return status;
- }
- /* Second test should rollover */
- packets = 65535;
- roc = 0;
- status = test_set_receiver_roc(packets - 1, roc);
- if (status) {
- return status;
- }
- status = test_set_receiver_roc(packets, roc);
- if (status) {
- return status;
- }
- /* Now the rollover counter should be 1 */
- roc = 1;
- status = test_set_receiver_roc(packets + 1, roc);
- if (status) {
- return status;
- }
- status = test_set_receiver_roc(packets + 60000, roc);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- srtp_err_status_t srtp_test_set_sender_roc()
- {
- uint32_t roc;
- uint16_t seq;
- srtp_err_status_t status;
- seq = 43210;
- roc = 0;
- status = test_set_sender_roc(seq, roc);
- if (status) {
- return status;
- }
- roc = 65535;
- status = test_set_sender_roc(seq, roc);
- if (status) {
- return status;
- }
- roc = 0xffff;
- status = test_set_sender_roc(seq, roc);
- if (status) {
- return status;
- }
- roc = 0xffff00;
- status = test_set_sender_roc(seq, roc);
- if (status) {
- return status;
- }
- roc = 0xfffffff0;
- status = test_set_sender_roc(seq, roc);
- if (status) {
- return status;
- }
- return srtp_err_status_ok;
- }
- /*
- * srtp policy definitions - these definitions are used above
- */
- // clang-format off
- unsigned char test_key[46] = {
- 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
- 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
- 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
- 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
- unsigned char test_key_2[46] = {
- 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
- 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
- 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
- 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
- 0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
- };
- unsigned char test_mki_id[TEST_MKI_ID_SIZE] = {
- 0xe1, 0xf9, 0x7a, 0x0d
- };
- unsigned char test_mki_id_2[TEST_MKI_ID_SIZE] = {
- 0xf3, 0xa1, 0x46, 0x71
- };
- // clang-format on
- const srtp_policy_t default_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 16, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 16, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- const srtp_policy_t aes_only_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 0, /* auth tag length in octets */
- sec_serv_conf /* security services flag */
- },
- {
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 0, /* auth tag length in octets */
- sec_serv_conf /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- const srtp_policy_t hmac_only_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 4, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 4, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* Number of Master keys associated with the policy */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- #ifdef GCM
- const srtp_policy_t aes128_gcm_8_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_GCM_128, /* cipher type */
- SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_GCM_128, /* cipher type */
- SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- const srtp_policy_t aes128_gcm_8_cauth_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_GCM_128, /* cipher type */
- SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_GCM_128, /* cipher type */
- SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- const srtp_policy_t aes256_gcm_8_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_GCM_256, /* cipher type */
- SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_GCM_256, /* cipher type */
- SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- const srtp_policy_t aes256_gcm_8_cauth_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_GCM_256, /* cipher type */
- SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_GCM_256, /* cipher type */
- SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 8, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- #endif
- const srtp_policy_t null_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 0, /* auth tag length in octets */
- sec_serv_none /* security services flag */
- },
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_NULL_AUTH, /* authentication func type */
- 0, /* auth key length in octets */
- 0, /* auth tag length in octets */
- sec_serv_none /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- // clang-format off
- unsigned char test_256_key[46] = {
- 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
- 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
- 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
- 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
- 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
- 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
- };
- unsigned char test_256_key_2[46] = {
- 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
- 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
- 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
- 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
- 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
- 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
- };
- srtp_master_key_t master_256_key_1 = {
- test_256_key,
- test_mki_id,
- TEST_MKI_ID_SIZE
- };
- srtp_master_key_t master_256_key_2 = {
- test_256_key_2,
- test_mki_id_2,
- TEST_MKI_ID_SIZE
- };
- srtp_master_key_t *test_256_keys[2] = {
- &master_key_1,
- &master_key_2
- };
- // clang-format on
- const srtp_policy_t aes_256_hmac_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_ICM_256, /* cipher type */
- SRTP_AES_ICM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_ICM_256, /* cipher type */
- SRTP_AES_ICM_256_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_256_keys,
- 2, /* indicates the number of Master keys */
- NULL, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- // clang-format off
- uint8_t ekt_test_key[16] = {
- 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
- 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
- };
- // clang-format on
- #include "ekt.h"
- // clang-format off
- srtp_ekt_policy_ctx_t ekt_test_policy = {
- 0xa5a5, /* SPI */
- SRTP_EKT_CIPHER_AES_128_ECB,
- ekt_test_key,
- NULL
- };
- // clang-format on
- const srtp_policy_t hmac_only_with_ekt_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 4, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- {
- SRTP_NULL_CIPHER, /* cipher type */
- 0, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 20, /* auth key length in octets */
- 4, /* auth tag length in octets */
- sec_serv_auth /* security services flag */
- },
- NULL,
- (srtp_master_key_t **)test_keys,
- 2, /* indicates the number of Master keys */
- &ekt_test_policy, /* indicates that EKT is not in use */
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
- /*
- * an array of pointers to the policies listed above
- *
- * This array is used to test various aspects of libSRTP for
- * different cryptographic policies. The order of the elements
- * matters - the timing test generates output that can be used
- * in a plot (see the gnuplot script file 'timing'). If you
- * add to this list, you should do it at the end.
- */
- // clang-format off
- const srtp_policy_t *policy_array[] = {
- &hmac_only_policy,
- &aes_only_policy,
- &default_policy,
- #ifdef GCM
- &aes128_gcm_8_policy,
- &aes128_gcm_8_cauth_policy,
- &aes256_gcm_8_policy,
- &aes256_gcm_8_cauth_policy,
- #endif
- &null_policy,
- &aes_256_hmac_policy,
- &hmac_only_with_ekt_policy,
- NULL
- };
- // clang-format on
- const srtp_policy_t wildcard_policy = {
- { ssrc_any_outbound, 0 }, /* SSRC */
- {
- /* SRTP policy */
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 16, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- {
- /* SRTCP policy */
- SRTP_AES_ICM_128, /* cipher type */
- SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
- SRTP_HMAC_SHA1, /* authentication func type */
- 16, /* auth key length in octets */
- 10, /* auth tag length in octets */
- sec_serv_conf_and_auth /* security services flag */
- },
- test_key,
- NULL,
- 0,
- NULL,
- 128, /* replay window size */
- 0, /* retransmission not allowed */
- NULL, /* no encrypted extension headers */
- 0, /* list of encrypted extension headers is empty */
- NULL
- };
|