You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
| 
 | |
| #include "SrtpStream.h"
 | |
| #include <android/log.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| #define AES_BLOCK_SIZE    16
 | |
| 
 | |
| #define TAG "SrtpStream"
 | |
| 
 | |
| SrtpStream::SrtpStream(SrtpStreamParameters *parameters) :
 | |
|   parameters(parameters)
 | |
| {}
 | |
| 
 | |
| SrtpStream::~SrtpStream() {
 | |
|   if (parameters != NULL) {
 | |
|     delete parameters;
 | |
|   }
 | |
| }
 | |
| 
 | |
| int SrtpStream::init() {
 | |
|   if (AES_set_encrypt_key(parameters->cipherKey, SRTP_AES_KEY_SIZE * 8, &key) != 0) {
 | |
|     __android_log_print(ANDROID_LOG_WARN, TAG, "Failed to set AES key!");
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| void SrtpStream::setIv(int64_t logicalSequence, uint32_t ssrc, uint8_t *salt, uint8_t *iv) {
 | |
|   memset(iv, 0, AES_BLOCK_SIZE);
 | |
|   memcpy(iv, salt, SRTP_SALT_SIZE);
 | |
| 
 | |
|   iv[6]  ^= (uint8_t)(ssrc >> 8);
 | |
|   iv[7]  ^= (uint8_t)(ssrc);
 | |
|   iv[8]  ^= (uint8_t)(logicalSequence >> 40);
 | |
|   iv[9]  ^= (uint8_t)(logicalSequence >> 32);
 | |
|   iv[10] ^= (uint8_t)(logicalSequence >> 24);
 | |
|   iv[11] ^= (uint8_t)(logicalSequence >> 16);
 | |
|   iv[12] ^= (uint8_t)(logicalSequence >> 8);
 | |
|   iv[13] ^= (uint8_t)(logicalSequence);
 | |
| }
 | |
| 
 | |
| 
 | |
| int SrtpStream::decrypt(RtpPacket &packet, int64_t logicalSequence) {
 | |
|   uint8_t iv[AES_BLOCK_SIZE];
 | |
|   uint8_t ecount[AES_BLOCK_SIZE];
 | |
|   uint8_t ourMac[SRTP_MAC_SIZE];
 | |
| 
 | |
|   uint32_t num    = 0;
 | |
|   uint32_t digest = 0;
 | |
| 
 | |
|   setIv(logicalSequence, packet.getSsrc(), parameters->salt, iv);
 | |
|   memset(ecount, 0, sizeof(ecount));
 | |
| 
 | |
|   if (packet.getPayloadLen() < (SRTP_MAC_SIZE + 1)) {
 | |
|     __android_log_print(ANDROID_LOG_WARN, TAG, "Packet shorter than MAC!");
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   HMAC(EVP_sha1(), parameters->macKey, SRTP_MAC_KEY_SIZE,
 | |
|        (uint8_t*)packet.getSerializedPacket(), packet.getSerializedPacketLen() - SRTP_MAC_SIZE, ourMac, &digest);
 | |
| 
 | |
|   if (memcmp(ourMac, packet.getSerializedPacket() + packet.getSerializedPacketLen() - SRTP_MAC_SIZE,
 | |
|       SRTP_MAC_SIZE) != 0)
 | |
|   {
 | |
|     __android_log_print(ANDROID_LOG_WARN, TAG, "MAC comparison failed!");
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   packet.setPayloadLen(packet.getPayloadLen() - SRTP_MAC_SIZE);
 | |
| 
 | |
|   AES_ctr128_encrypt((uint8_t*)packet.getPayload(), (uint8_t*)packet.getPayload(),
 | |
|                      packet.getPayloadLen(), &key, iv, ecount, &num);
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int SrtpStream::encrypt(RtpPacket &packet, int64_t logicalSequence) {
 | |
|   uint8_t iv[AES_BLOCK_SIZE];
 | |
|   uint8_t ecount[AES_BLOCK_SIZE];
 | |
| 
 | |
|   uint32_t num    = 0;
 | |
|   uint32_t digest = 0;
 | |
| 
 | |
|   setIv(logicalSequence, packet.getSsrc(), parameters->salt, iv);
 | |
|   memset(ecount, 0, sizeof(ecount));
 | |
| 
 | |
|   AES_ctr128_encrypt((uint8_t*)packet.getPayload(), (uint8_t*)packet.getPayload(), packet.getPayloadLen(), &key, iv, ecount, &num);
 | |
| 
 | |
|   HMAC(EVP_sha1(), parameters->macKey, SRTP_MAC_KEY_SIZE,
 | |
|        (uint8_t*)packet.getSerializedPacket(), packet.getSerializedPacketLen(),
 | |
|        (uint8_t*)packet.getSerializedPacket() + packet.getSerializedPacketLen(), &digest);
 | |
| 
 | |
|   packet.setPayloadLen(packet.getPayloadLen() + SRTP_MAC_SIZE);
 | |
| 
 | |
|   return 0;
 | |
| }
 |