@@ -71,6 +71,10 @@ public class SdlProtocolBase {
7171 private final static String FailurePropagating_Msg = "Failure propagating " ;
7272
7373 private static final int TLS_MAX_RECORD_SIZE = 16384 ;
74+ private final static int TLS_RECORD_HEADER_SIZE = 5 ;
75+ private final static int TLS_RECORD_MES_AUTH_CDE_SIZE = 32 ;
76+ private final static int TLS_MAX_RECORD_PADDING_SIZE = 256 ;
77+ private final static int TLS_MAX_DATA_TO_ENCRYPT_SIZE = TLS_MAX_RECORD_SIZE - TLS_RECORD_HEADER_SIZE - TLS_RECORD_MES_AUTH_CDE_SIZE - TLS_MAX_RECORD_PADDING_SIZE ;
7478
7579 private static final int PRIMARY_TRANSPORT_ID = 1 ;
7680 private static final int SECONDARY_TRANSPORT_ID = 2 ;
@@ -561,7 +565,8 @@ public void endSession(byte sessionID) {
561565 public void sendMessage (ProtocolMessage protocolMsg ) {
562566 SessionType sessionType = protocolMsg .getSessionType ();
563567 byte sessionID = protocolMsg .getSessionID ();
564-
568+ boolean requiresEncryption = protocolMsg .getPayloadProtected ();
569+ SdlSecurityBase sdlSec = null ;
565570 byte [] data ;
566571 if (protocolVersion .getMajor () > 1 && sessionType != SessionType .NAV && sessionType != SessionType .PCM ) {
567572 if (sessionType .eq (SessionType .CONTROL )) {
@@ -590,21 +595,15 @@ public void sendMessage(ProtocolMessage protocolMsg) {
590595 data = protocolMsg .getData ();
591596 }
592597
593- if (iSdlProtocol != null && protocolMsg .getPayloadProtected ()) {
594-
595- if (data != null && data .length > 0 ) {
596- byte [] dataToRead = new byte [TLS_MAX_RECORD_SIZE ];
597- SdlSecurityBase sdlSec = iSdlProtocol .getSdlSecurity ();
598- if (sdlSec == null )
599- return ;
600-
601- Integer iNumBytes = sdlSec .encryptData (data , dataToRead );
602- if ((iNumBytes == null ) || (iNumBytes <= 0 ))
603- return ;
604-
605- byte [] encryptedData = new byte [iNumBytes ];
606- System .arraycopy (dataToRead , 0 , encryptedData , 0 , iNumBytes );
607- data = encryptedData ;
598+ if (requiresEncryption ) {
599+ if (iSdlProtocol == null ) {
600+ DebugTool .logError (TAG , "Unable to encrypt packet, protocol callback was null" );
601+ return ;
602+ }
603+ sdlSec = iSdlProtocol .getSdlSecurity ();
604+ if (sdlSec == null ) {
605+ DebugTool .logError (TAG , "Unable to encrypt packet, security library not found" );
606+ return ;
608607 }
609608 }
610609
@@ -616,24 +615,25 @@ public void sendMessage(ProtocolMessage protocolMsg) {
616615 return ;
617616 }
618617
619- synchronized ( messageLock ) {
620- if ( data != null && data . length > getMtu (sessionType )) {
618+ //Set the MTU according to session MTU provided by the IVI or the max data size for encryption if required
619+ final Long mtu = requiresEncryption ? TLS_MAX_DATA_TO_ENCRYPT_SIZE : getMtu (sessionType );
621620
621+ synchronized (messageLock ) {
622+ if (data != null && data .length > mtu ) {
623+ //Since the packet is larger than the mtu size, it will be sent as a multi-frame packet
622624 messageID ++;
623625
624626 // Assemble first frame.
625- Long mtu = getMtu (sessionType );
626- int frameCount = Long .valueOf (data .length / mtu ).intValue ();
627- if (data .length % mtu > 0 ) {
628- frameCount ++;
629- }
627+ int frameCount = (int ) Math .ceil (data .length / (double ) mtu );
628+
630629 byte [] firstFrameData = new byte [8 ];
631630 // First four bytes are data size.
632631 System .arraycopy (BitConverter .intToByteArray (data .length ), 0 , firstFrameData , 0 , 4 );
633632 // Second four bytes are frame count.
634633 System .arraycopy (BitConverter .intToByteArray (frameCount ), 0 , firstFrameData , 4 , 4 );
635634
636- SdlPacket firstHeader = SdlPacketFactory .createMultiSendDataFirst (sessionType , sessionID , messageID , (byte ) protocolVersion .getMajor (), firstFrameData , protocolMsg .getPayloadProtected ());
635+ //NOTE: First frames cannot be encrypted because their payloads need to be exactly 8 bytes
636+ SdlPacket firstHeader = SdlPacketFactory .createMultiSendDataFirst (sessionType , sessionID , messageID , (byte ) protocolVersion .getMajor (), firstFrameData , false );
637637 firstHeader .setPriorityCoefficient (1 + protocolMsg .priorityCoefficient );
638638 firstHeader .setTransportRecord (activeTransports .get (sessionType ));
639639 //Send the first frame
@@ -642,33 +642,58 @@ public void sendMessage(ProtocolMessage protocolMsg) {
642642 int currentOffset = 0 ;
643643 byte frameSequenceNumber = 0 ;
644644
645+ byte [] dataBuffer , encryptedData ;
645646 for (int i = 0 ; i < frameCount ; i ++) {
646- if (i < (frameCount - 1 )) {
647- ++frameSequenceNumber ;
648- if (frameSequenceNumber ==
649- SdlPacket .FRAME_INFO_FINAL_CONNESCUTIVE_FRAME ) {
650- // we can't use 0x00 as frameSequenceNumber, because
651- // it's reserved for the last frame
652- ++frameSequenceNumber ;
653- }
654- } else {
647+
648+ frameSequenceNumber ++;
649+ if (i == frameCount - 1 ) {
655650 frameSequenceNumber = SdlPacket .FRAME_INFO_FINAL_CONNESCUTIVE_FRAME ;
656- } // end-if
651+ }
657652
658653 int bytesToWrite = data .length - currentOffset ;
659654 if (bytesToWrite > mtu ) {
660655 bytesToWrite = mtu .intValue ();
661656 }
662- SdlPacket consecHeader = SdlPacketFactory .createMultiSendDataRest (sessionType , sessionID , bytesToWrite , frameSequenceNumber , messageID , (byte ) protocolVersion .getMajor (), data , currentOffset , bytesToWrite , protocolMsg .getPayloadProtected ());
663- consecHeader .setTransportRecord (activeTransports .get (sessionType ));
664- consecHeader .setPriorityCoefficient (i + 2 + protocolMsg .priorityCoefficient );
665- handlePacketToSend (consecHeader );
657+
658+ SdlPacket consecutiveFrame ;
659+ if (requiresEncryption ) {
660+ //Retrieve a chunk of the data into a temporary buffer to be encrypted
661+ dataBuffer = new byte [bytesToWrite ];
662+ System .arraycopy (data , currentOffset , dataBuffer , 0 , bytesToWrite );
663+
664+ encryptedData = new byte [TLS_MAX_RECORD_SIZE ];
665+ Integer numberOfBytesEncrypted = sdlSec .encryptData (dataBuffer , encryptedData );
666+ if (numberOfBytesEncrypted == null || (numberOfBytesEncrypted <= 0 )) {
667+ DebugTool .logError (TAG , "Unable to encrypt data" );
668+ return ;
669+ }
670+
671+ consecutiveFrame = SdlPacketFactory .createMultiSendDataRest (sessionType , sessionID , numberOfBytesEncrypted , frameSequenceNumber , messageID , (byte ) protocolVersion .getMajor (), encryptedData , 0 , numberOfBytesEncrypted , true );
672+ } else {
673+ consecutiveFrame = SdlPacketFactory .createMultiSendDataRest (sessionType , sessionID , bytesToWrite , frameSequenceNumber , messageID , (byte ) protocolVersion .getMajor (), data , currentOffset , bytesToWrite , false );
674+ }
675+
676+ consecutiveFrame .setTransportRecord (activeTransports .get (sessionType ));
677+ consecutiveFrame .setPriorityCoefficient (i + 2 + protocolMsg .priorityCoefficient );
678+ handlePacketToSend (consecutiveFrame );
666679 currentOffset += bytesToWrite ;
667680 }
668681 } else {
669682 messageID ++;
683+ if (requiresEncryption && data != null && data .length > 0 ) {
684+ //Encrypt the data before sending
685+ byte [] encryptedData = new byte [TLS_MAX_RECORD_SIZE ];
686+ Integer numberOfBytesEncrypted = sdlSec .encryptData (data , encryptedData );
687+ if (numberOfBytesEncrypted == null || (numberOfBytesEncrypted <= 0 )) {
688+ DebugTool .logError (TAG , "Unable to encrypt data" );
689+ return ;
690+ }
691+ //Put the encrypted bytes back into the data array
692+ data = new byte [numberOfBytesEncrypted ];
693+ System .arraycopy (encryptedData , 0 , data , 0 , numberOfBytesEncrypted );
694+ }
670695 int dataLength = data != null ? data .length : 0 ;
671- SdlPacket header = SdlPacketFactory .createSingleSendData (sessionType , sessionID , dataLength , messageID , (byte ) protocolVersion .getMajor (), data , protocolMsg . getPayloadProtected () );
696+ SdlPacket header = SdlPacketFactory .createSingleSendData (sessionType , sessionID , dataLength , messageID , (byte ) protocolVersion .getMajor (), data , requiresEncryption );
672697 header .setPriorityCoefficient (protocolMsg .priorityCoefficient );
673698 header .setTransportRecord (activeTransports .get (sessionType ));
674699 handlePacketToSend (header );
0 commit comments