⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfccrypto.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000-2004.  All Rights Reserved. *  * Contributor(s):  *		Dave Mackie		  dmackie@cisco.com *		Mark Baugher		  mbaugher@cisco.com *              Alix Marchandise-Franquet alix@cisco.com *              Alex Vanzella             alexv@cisco.com */#include <mp4av_common.h>// definitions// mjb: ismacryp declarations#define ISMACRYP_CRYPTO_SUITE 0                 //index into settings array#define ISMACRYP_CRYPTO_SUITE_DEFAULT 0#define ISMACRYP_IV_LENGTH 1                    //index into settings array#define ISMACRYP_IV_LENGTH_DEFAULT 4#define ISMACRYP_IV_DELTA_LENGTH 2              //index into settings array#define ISMACRYP_IV_DELTA_LENGTH_DEFAULT 0#define ISMACRYP_SELECTIVE_ENCRYPTION 3         //index into settings array#define ISMACRYP_SELECTIVE_ENCRYPTION_DEFAULT 0#define ISMACRYP_KEY_INDICATOR_LENGTH 4         //index into settings array#define ISMACRYP_KEY_INDICATOR_LENGTH_DEFAULT 0#define ISMACRYP_KEY_INDICATOR_PER_AU 5         //index into settings array#define ISMACRYP_KEY_INDICATOR_PER_AU_DEFAULT 0#define ISMACRYP_SALT_LENGTH 6                  //index into settings array#define ISMACRYP_SALT_LENGTH_DEFAULT 8          //number of bytes in salt key#define ISMACRYP_KEY_LENGTH 7                   //index into settings array#define ISMACRYP_KEY_LENGTH_DEFAULT 16          //number of bytes in master key#define ISMACRYP_KEY_COUNT 8                    //index into settings array#define ISMACRYP_MAX_KEYS 6                     //max number of salts and keys#define ISMACRYP_MAX_KEY_LENGTH ISMACRYP_KEY_LENGTH_DEFAULT#define ISMACRYP_MAX_SALT_LENGTH ISMACRYP_SALT_LENGTH_DEFAULT// default scheme is "iAEC"#define ISMACRYP_DEFAULT_SCHEME_HEX  0x69414543#define ISMACRYP_SDP_CONFIG_MAX_LEN                256#define ISMACRYP_SDP_ADDITIONAL_CONFIG_MAX_LEN     256// change this if any of the following strings is longer than 64#define ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN 64// if any of these strings is longer than ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,// change ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN to reflect longest string + 1 for '\0'// pay special attention to the key string (str 7).#define ISMACRYP_SDP_CONFIG_STR_1    " ISMACrypCryptoSuite=AES_CTR_128;"#define ISMACRYP_SDP_CONFIG_STR_2    " ISMACrypIVLength=%u;"#define ISMACRYP_SDP_CONFIG_STR_3    " ISMACrypIVDeltaLength=%u;"#define ISMACRYP_SDP_CONFIG_STR_4    " ISMACrypSelectiveEncryption=%u;"#define ISMACRYP_SDP_CONFIG_STR_5    " ISMACrypKeyIndicatorLength=%u;"#define ISMACRYP_SDP_CONFIG_STR_6    " ISMACrypKeyIndicatorPerAU=%u;"#define ISMACRYP_SDP_CONFIG_STR_7    " ISMACrypKey=(key)%s/%u"// These structs hold ISMACRYP protocol variables related to an// encryption session. Used to construct SDP signalling information// for the session.typedef struct ismacryp_config_table {        u_int8_t        lifetime;        u_int8_t        settings[9];        u_int8_t*       salts[ISMACRYP_MAX_KEYS];        u_int8_t*       keys[ISMACRYP_MAX_KEYS];        char            indices[ISMACRYP_MAX_KEYS][255];} ISMACrypConfigTable_t;typedef struct ismaCrypSampleHdrDataInfo {  u_int8_t hasEncField; // if selective encryption  u_int8_t isEncrypted;  u_int8_t hasIVField;  u_int8_t hasKIField;} ismaCrypSampleHdrDataInfo_t;// forward declarations.static bool MP4AV_RfcCryptoConcatenator(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId, 	MP4TrackId hintTrackId,	u_int8_t samplesThisHint, 	MP4SampleId* pSampleIds, 	MP4Duration hintDuration,	u_int16_t maxPayloadSize,	mp4av_ismacrypParams *icPp,	bool isInterleaved);static bool MP4AV_RfcCryptoFragmenter(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId, 	MP4TrackId hintTrackId,	MP4SampleId sampleId, 	u_int32_t sampleSize, 	MP4Duration sampleDuration,	u_int16_t maxPayloadSize,	mp4av_ismacrypParams *icPp);/* start sdp code */// ismac_table will contain all the setting to create the SDP// initialize this table with settings from the ismacryp library static bool InitISMACrypConfigTable (ISMACrypConfigTable_t* ismac_table,	mp4av_ismacrypParams *icPp){	u_int32_t        	fourCC;	u_int8_t	        yes;	ismac_table->settings[ISMACRYP_KEY_COUNT]=icPp->key_count;	if(!ismac_table || ismac_table->salts[0] || ismac_table->keys[0])		return false;	if(!(ismac_table->salts[0]=(u_int8_t*)malloc(icPp->salt_len)))           return false;	if(!(ismac_table->keys[0]=(u_int8_t*)malloc(icPp->key_len))){        	free(ismac_table->salts[0]);        	return false;        }        ismac_table->settings[ISMACRYP_KEY_LENGTH] = icPp->key_len;	ismac_table->settings[ISMACRYP_SALT_LENGTH] = icPp->salt_len;	ismac_table->lifetime = icPp->key_life;        memcpy(ismac_table->keys[0],icPp->key,icPp->key_len);        memcpy(ismac_table->salts[0],icPp->salt,icPp->salt_len);        ismac_table->settings[ISMACRYP_KEY_INDICATOR_LENGTH] = icPp->key_ind_len;        yes = icPp->key_ind_perau;	if (!yes) ismac_table->settings[ISMACRYP_KEY_INDICATOR_PER_AU] = 0;	else ismac_table->settings[ISMACRYP_KEY_INDICATOR_PER_AU] = 1;	yes = icPp->selective_enc;	if (!yes) ismac_table->settings[ISMACRYP_SELECTIVE_ENCRYPTION] = 0;	else ismac_table->settings[ISMACRYP_SELECTIVE_ENCRYPTION] = 1;        ismac_table->settings[ISMACRYP_IV_DELTA_LENGTH] = icPp->delta_iv_len;	ismac_table->settings[ISMACRYP_IV_LENGTH] = icPp->delta_iv_len;        fourCC = icPp->scheme;	if (fourCC == ISMACRYP_DEFAULT_SCHEME_HEX)		ismac_table->settings[ISMACRYP_CRYPTO_SUITE]=0;	else return false;	return true; }// Checks validity of the ismacryp SDP settings returned from the ismacryp librarystatic bool MP4AV_RfcCryptoPolicyOk (ISMACrypConfigTable_t* ismac_table){	if(ismac_table->settings[ISMACRYP_CRYPTO_SUITE] 		!= ISMACRYP_CRYPTO_SUITE_DEFAULT) 		return false;	if(ismac_table->settings[ISMACRYP_IV_LENGTH] >8)  		return false;	if(ismac_table->settings[ISMACRYP_IV_DELTA_LENGTH] > 2) 		return false;	if(ismac_table->settings[ISMACRYP_SELECTIVE_ENCRYPTION] > 1)		return false;	if(ismac_table->settings[ISMACRYP_KEY_INDICATOR_PER_AU] > 1)		return false;	if((ismac_table->settings[ISMACRYP_SALT_LENGTH] 			!= ISMACRYP_SALT_LENGTH_DEFAULT) 		|| (ismac_table->settings[ISMACRYP_KEY_LENGTH] 			!= ISMACRYP_KEY_LENGTH_DEFAULT)) return false;	return true;}// assemble the ismacryp SDP string into sISMACrypConfigstatic bool MP4AV_RfcCryptoConfigure(ISMACrypConfigTable_t* ismac_table,	char** sISMACrypConfig){        if (ismac_table == NULL )           return false;        *sISMACrypConfig = (char *)malloc(ISMACRYP_SDP_CONFIG_MAX_LEN);        if (*sISMACrypConfig == NULL )           return false;        char temp[ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN];        int lenstr1, lenstr2, totlen;        // first string is ISMACrypCryptoSuite        totlen = strlen(ISMACRYP_SDP_CONFIG_STR_1) + 1; // add 1 for '\0'        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN - 1 ) 	  snprintf(*sISMACrypConfig, totlen, "%s", ISMACRYP_SDP_CONFIG_STR_1);        else {          free(*sISMACrypConfig);          return false;        }        // second string is ISMACrypIVLength        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_2,                        ismac_table->settings[ISMACRYP_IV_LENGTH]);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);          return false;        }        // third string is ISMACrypIVDeltaLength        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_3,                        ismac_table->settings[ISMACRYP_IV_DELTA_LENGTH]);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);          return false;        }        // fourth string is ISMACrypSelectiveEncryption        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_4,                        ismac_table->settings[ISMACRYP_SELECTIVE_ENCRYPTION]);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);          return false;        }        // fifth string is ISMACrypKeyIndicatorLength        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_5,                        ismac_table->settings[ISMACRYP_KEY_INDICATOR_LENGTH]);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);          return false;        }        // sixth string is ISMACrypKeyIndicatorPerAU        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_6,                        ismac_table->settings[ISMACRYP_KEY_INDICATOR_PER_AU]);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);          return false;        }	// convert the concatenated, binary keys to Base 64	u_int8_t  keymat[ISMACRYP_KEY_LENGTH_DEFAULT+ISMACRYP_SALT_LENGTH_DEFAULT];         memcpy(keymat,ismac_table->salts[0],ISMACRYP_SALT_LENGTH_DEFAULT);        memcpy(&keymat[ISMACRYP_SALT_LENGTH_DEFAULT],ismac_table->keys[0],ISMACRYP_KEY_LENGTH_DEFAULT);	char* base64keymat = MP4BinaryToBase64((u_int8_t*)keymat,                                      ISMACRYP_SALT_LENGTH_DEFAULT + ISMACRYP_KEY_LENGTH_DEFAULT);        // seventh string is ISMACrypKey        snprintf(temp, ISMACRYP_SDP_CONFIG_MAX_SUBSTR_LEN,                       ISMACRYP_SDP_CONFIG_STR_7,                        base64keymat, ismac_table->lifetime);        lenstr1 = strlen(*sISMACrypConfig);         lenstr2 = strlen(temp) + 1; // add 1 for '\0'        totlen = lenstr1 + lenstr2;        if ( totlen < ISMACRYP_SDP_CONFIG_MAX_LEN )          snprintf( *sISMACrypConfig+lenstr1,lenstr2, "%s", temp);        else {          free(*sISMACrypConfig);	  free(base64keymat);          return false;        }	free(base64keymat);	return true;}/* end sdp code */// MP4AV_CryptoAudioConsecutiveHinter: figures out how to put the samples into packets// When a hint is defined (the sample ids of the hint are in pSampleIds)// call MP4AV_RfcCryptoConcatenator to create it // Note: This is a modified clone of MP4AV_AudioConsecutiveHinter in audio_hinters.cppstatic bool MP4AV_CryptoAudioConsecutiveHinter(MP4FileHandle mp4File, 					       MP4TrackId mediaTrackId, 					       MP4TrackId hintTrackId,					       MP4Duration sampleDuration, 					       u_int8_t perPacketHeaderSize,					       u_int8_t perSampleHeaderSize,					       u_int8_t maxSamplesPerPacket,					       u_int16_t maxPayloadSize,					       MP4AV_AudioSampleSizer pSizer,					       mp4av_ismacrypParams *icPp){  bool rc;  u_int32_t numSamples =     MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);  u_int16_t bytesThisHint = perPacketHeaderSize;  u_int16_t samplesThisHint = 0;  MP4SampleId* pSampleIds =     new MP4SampleId[maxSamplesPerPacket];  for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {    u_int32_t sampleSize =       (*pSizer)(mp4File, mediaTrackId, sampleId);    // sample won't fit in this packet    // or we've reached the limit on samples per packet    if ((int16_t)(sampleSize + perSampleHeaderSize) 	> maxPayloadSize - bytesThisHint 	|| samplesThisHint == maxSamplesPerPacket) {      if (samplesThisHint > 0) {	rc = MP4AV_RfcCryptoConcatenator(mp4File, mediaTrackId, hintTrackId,					 samplesThisHint, pSampleIds,					 samplesThisHint * sampleDuration,					 maxPayloadSize, icPp, false);	if (!rc) {          delete [] pSampleIds;	  return false;	}      }      // start a new hint       samplesThisHint = 0;      bytesThisHint = perPacketHeaderSize;      // fall thru    }    // sample is less than remaining payload size    if ((int16_t)(sampleSize + perSampleHeaderSize)	<= maxPayloadSize - bytesThisHint) {      // add it to this hint      bytesThisHint += (sampleSize + perSampleHeaderSize);      pSampleIds[samplesThisHint++] = sampleId;    } else {       // jumbo frame, need to fragment it      rc = MP4AV_RfcCryptoFragmenter(mp4File, mediaTrackId, hintTrackId, sampleId, 			  sampleSize, sampleDuration, maxPayloadSize, icPp);	      if (!rc) {        delete [] pSampleIds;	return false;      }      // start a new hint       samplesThisHint = 0;      bytesThisHint = perPacketHeaderSize;    }  }  if (samplesThisHint > 0) {    rc = MP4AV_RfcCryptoConcatenator(mp4File, mediaTrackId, hintTrackId,				     samplesThisHint, pSampleIds,				     samplesThisHint * sampleDuration,				     maxPayloadSize, icPp, false);    if (!rc) {      delete [] pSampleIds;      return false;    }  }  delete [] pSampleIds;  return true;}// MP4AV_CryptoAudioInterleaveHinter: figures out how to put the samples into packets// When a hint is defined (the sample ids of the hint are in pSampleIds)// call MP4AV_RfcCryptoConcatenator to create it. The samples are interleaved. // Note: This is a modified clone of MP4AV_AudioInterleaveHinter in audio_hinters.cppstatic bool MP4AV_CryptoAudioInterleaveHinter(MP4FileHandle mp4File, 					      MP4TrackId mediaTrackId, 					      MP4TrackId hintTrackId,					      MP4Duration sampleDuration, 					      u_int8_t stride, 					      u_int8_t bundle,					      u_int16_t maxPayloadSize,					      mp4av_ismacrypParams *icPp){  bool rc;  u_int32_t numSamples =     MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);    MP4SampleId* pSampleIds = new MP4SampleId[bundle];  uint32_t sampleIds = 0;  for (u_int32_t i = 1; i <= numSamples; i += stride * bundle) {    for (u_int32_t j = 0; j < stride; j++) {      u_int32_t k;      for (k = 0; k < bundle; k++) {		MP4SampleId sampleId = i + j + (k * stride);	// out of samples for this bundle	if (sampleId > numSamples) {	  break;	}	// add sample to this hint	pSampleIds[k] = sampleId;	sampleIds++;      }      if (k == 0) {	break;      }      // compute hint duration      // note this is used to control the RTP timestamps       // that are emitted for the packet,      // it isn't the actual duration of the samples in the packet      MP4Duration hintDuration;      if (j + 1 == stride) {	// at the end of the track	if (i + (stride * bundle) > numSamples) {	  hintDuration = ((numSamples - i) - j) * sampleDuration;	  if (hintDuration == 0) {	    hintDuration = sampleDuration;	  }	} else {	  hintDuration = ((stride * bundle) - j) * sampleDuration;	}      } else {	hintDuration = sampleDuration;      }      // write hint      rc = MP4AV_RfcCryptoConcatenator(mp4File, mediaTrackId, hintTrackId, k, 				       pSampleIds, hintDuration, maxPayloadSize, 				       icPp, true);      sampleIds = 0;            if (!rc) {        delete [] pSampleIds;	return false;      }    }  }  delete [] pSampleIds;    return true;}// returns the size of the ismacryp sample header:// selective encryption flag, IV, key indicatorstatic u_int32_t MP4AV_GetIsmaCrypSampleHdrSize (					ismaCrypSampleHdrDataInfo_t iCrypSampleHdrInfo, 					u_int8_t IVlen, 				        u_int8_t KIlen){  // the ismaCryp sample header always has the IV and the KI  u_int32_t iCrypSampleHdrSize = (iCrypSampleHdrInfo.hasEncField ? 1: 0)     + IVlen  + KIlen;  return iCrypSampleHdrSize;}// get the key indicator length, the IV length and the selective // encryption flag from the iSFM atom in the filestatic bool MP4AV_GetiSFMSettings(MP4FileHandle mp4File, 				  MP4TrackId mediaTrackId,				  u_int8_t *useSelectiveEnc, 				  u_int8_t *KIlen, 				  u_int8_t *IVlen,				  bool isAudio){  const char *part1    = "mdia.minf.stbl.stsd.";  const char *part2a   = "enca";  const char *part2v   = "encv";  const char *part3    = ".sinf.schi.iSFM.";  const char *part4se  = "selective-encryption";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -