SRTP

1. (uint32_t *)p+3,
计算原理,指针指向的地址向下移动三个位置,因为地址为4个字节的类型,向下移动三个,即移动了3*4=12个字节, 指针移向了新地址
2. (enc_start - (uint32_t *)hdr) << 2
3<<2=12
指针地址差左移两位,得到的结果正好是12
3. Srtp 要加密的区域是172-12=160 byte,即去除头部的长度

4. 校验,从RTP 头部地址hdr起,最终校验的值存放的地址为头地址加长度172,即为存放校验位的地址
auth_start = (uint32_t *)hdr;
auth_tag = (uint8_t *)hdr + *pkt_octet_len;
5. Srtp_protect function

加密部分,从去除头部地址12个字节的地方开始
  char * hexstr;
  hexstr = octet_string_hex_string(enc_start, enc_octet_len);
  writelog("hexstr1=%s",hexstr); //加密前原文
  if (enc_start) {
    status = cipher_encrypt(stream->rtp_cipher,
    (uint8_t *)enc_start, &enc_octet_len);
    if (status)
      return err_status_cipher_fail;
  }
  memset(hexstr,0,sizeof(hexstr));
  hexstr = octet_string_hex_string(enc_start, enc_octet_len);
  writelog("hexstr2=%s",hexstr);//加密后密文,长度不变



校验部分,从头部开始校验

if (auth_tag) {

     writelog("srtp auth tag: %s", octet_string_hex_string(auth_tag, tag_len));
    /* increase the packet length by the length of the auth tag */
    *pkt_octet_len += tag_len;
writelog("srtp auth tag new length: %d",  *pkt_octet_len); //长度增加
  }
6. 调用srtp_protect
srtp_protect(sender_srtp_ctx, &rtp.header, &nLen);
a. &msg.header, rtp 头部地址
b. &nLen,加密前的数据长度
c. 做两件事情,
• 从去除头部长度的地址起,进行加密,加密后长度不变
• 从头部开始进行校验,生成auth tag, 拼接在数据的末尾
• 把数据的长度+auth tag len, nLen被变化
7. 发送数据
write_to((char *)&rtp, nLen,  m_remote_addr, m_remote_data_port)
sendto(fd,
  (const char *)buf, nLen, 0, (struct sockaddr *)&sockAddr, sizeof(struct sockaddr_in));
8. Srtp_unprotect

a. 确定要校验的开始位置,从头部开始
b. 确定要解密的开始位置和结束位置,从去除头部字节的地址开始,到auth tag 前结束
校验部分
status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag); 
writelog("computed auth tag:    %s",octet_string_hex_string(tmp_tag, tag_len));//tag_len=4
       writelog("packet auth tag:    %s",octet_string_hex_string(auth_tag, tag_len));

解密部分
writelog("begin decrypt,enc_octet_len=%d",enc_octet_len);//160
  writelog("content =%s",octet_string_hex_string(enc_start, enc_octet_len));
  if (enc_start) {

    status = cipher_encrypt(stream->rtp_cipher,
    (uint8_t *)enc_start, &enc_octet_len);
    writelog("content =%s",octet_string_hex_string(enc_start, enc_octet_len));
    if (status)
      return err_status_cipher_fail;
  }

9. Writelog
static FILE *err_file = NULL;

void writelog(char *format, ...) {

    va_list args;

    va_start(args, format);

    if (err_file == NULL) {

        err_file = fopen("/srtp.log","w");
    }

    if (err_file != NULL) {
      vfprintf(err_file, format, args);
          fprintf(err_file, "\n");
    }
}

你可能感兴趣的:(r)