tested with Asterisk 11.17.1 --- include/asterisk/res_srtp.h (revision 371121) +++ include/asterisk/res_srtp.h (working copy) @@ -52,6 +52,8 @@ /* Crypto suites */ enum ast_srtp_suite { + AST_AES_CM_128_HMAC_SHA1_32_ROC_LE = -2, + AST_AES_CM_128_HMAC_SHA1_80_ROC_LE = -1, AST_AES_CM_128_HMAC_SHA1_80 = 1, AST_AES_CM_128_HMAC_SHA1_32 = 2, AST_F8_128_HMAC_SHA1_80 = 3 --- channels/chan_sip.c (revision 434288) +++ channels/chan_sip.c (working copy) @@ -33402,6 +33402,7 @@ static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a) { + unsigned int roll_over_counter_little_endian = 0; struct ast_rtp_engine_dtls *dtls; /* If no RTP instance exists for this media stream don't bother processing the crypto line */ @@ -33429,7 +33430,39 @@ return FALSE; } - if (sdp_crypto_process((*srtp)->crypto, a, rtp, *srtp) < 0) { + /* Nokia Symbian/S60 requires little-endian ROC; default of RFC is network + * order = big endian. Nokia Series 40 and Nokia Asha Software Platform are + * not affected and use network order. As User-Agent, these use NokiaModel, + * for example Nokia6300i and Nokia503. Nokia MeeGo/Maemo do not offer sRTP. + * Symbian/S60 uses *Type, Type is RA-x or RM-xxx, for example: + * a) Nokia RA-6 300.34.84 + * b) E66-1 RM-343 510.21.009 + * c) S60 RM-670 113.010.1506 + * + * http://www.nokiaport.de/?pid=models + * http://web.archive.org/web/20080416025322/http://www.forum.nokia.com/main/resources/technologies/voice_over_IP/voip_support_in_nokia_devices.html + * http://web.archive.org/web/20090528115458/http://www.forum.nokia.com/Technology_Topics/Mobile_Technologies/VoIP/Nokia_VoIP_Framework/VoIP_support_in_Nokia_devices.xhtml + * http://web.archive.org/web/20120309140131/http://www.developer.nokia.com/Community/Wiki/VoIP_support_in_Nokia_devices + * Nokia E63, Nokia E66, and Nokia E71 (only those) send no User-Agent on + * REGISTER and no while answering to an INVITE. Therefore, these phones + * cannot be catched/filtered by the code below. Calls initiated by these + * phones do work because the User-Agent is sent. If you have users using + * such phones to receive calls, consider to change the rtp->seqno from + * random to 0 (in res/res_rtp_asterisk.c:ast_rtp_new); then calls last at + * least 21 minutes. + */ + if (strstr(p->useragent, " RA-")) { + roll_over_counter_little_endian = 1; + } else if (strstr(p->useragent, " RM-")) { + roll_over_counter_little_endian = 1; + /* required for INVITE from Asterisk because session does not exchange User-Agent */ + } else if (p->relatedpeer && strstr(p->relatedpeer->useragent, " RA-")) { + roll_over_counter_little_endian = 1; + } else if (p->relatedpeer && strstr(p->relatedpeer->useragent, " RM-")) { + roll_over_counter_little_endian = 1; + } + + if (sdp_crypto_process((*srtp)->crypto, a, rtp, *srtp, roll_over_counter_little_endian) < 0) { return FALSE; } --- channels/sip/include/sdp_crypto.h (revision 371121) +++ channels/sip/include/sdp_crypto.h (working copy) @@ -57,7 +57,7 @@ * \retval 0 success * \retval nonzero failure */ -int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp); +int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp, unsigned int roc_le); /*! \brief Generate an SRTP a=crypto offer --- channels/sip/sdp_crypto.c (revision 432239) +++ channels/sip/sdp_crypto.c (working copy) @@ -185,7 +185,7 @@ return res; } -int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp) +int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp, unsigned int roc_le) { char *str = NULL; char *tag = NULL; @@ -232,10 +232,16 @@ if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) { suite_val = AST_AES_CM_128_HMAC_SHA1_80; + if (roc_le) { + suite_val = AST_AES_CM_128_HMAC_SHA1_80_ROC_LE; + } ast_set_flag(srtp, SRTP_CRYPTO_TAG_80); taglen = 80; } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) { suite_val = AST_AES_CM_128_HMAC_SHA1_32; + if (roc_le) { + suite_val = AST_AES_CM_128_HMAC_SHA1_32_ROC_LE; + } ast_set_flag(srtp, SRTP_CRYPTO_TAG_32); taglen = 32; } else { --- res/res_srtp.c (revision 426141) +++ res/res_srtp.c (working copy) @@ -278,6 +278,13 @@ static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite) { + if (suite == AST_AES_CM_128_HMAC_SHA1_32_ROC_LE) { + policy->sp.allow_repeat_tx = (policy->sp.allow_repeat_tx | 0x02); + suite = AST_AES_CM_128_HMAC_SHA1_32; + } else if (suite == AST_AES_CM_128_HMAC_SHA1_80_ROC_LE) { + policy->sp.allow_repeat_tx = (policy->sp.allow_repeat_tx | 0x02); + suite = AST_AES_CM_128_HMAC_SHA1_80; + } return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite); }