pub fn generate_encrypt<'a>(
        &self,
        out: &'a mut [u8],
        associated_data: &[u8],
        payload: &[u8],
    ) -> Result<&'a [u8], Error> {
        let olen = out.len();
        let alen = associated_data.len();
        let plen = payload.len();

        // Input sanity check
        if alen >= CCM_AAD_MAX_BYTES || plen >= CCM_PAYLOAD_MAX_BYTES {
            return Err(Error::UnsupportedSize);
        }
        if olen < plen + self.mlen {
            return Err(Error::InvalidOutSize);
        }

        // The sequence b for encryption is formatted as follows:
        // b = [FLAGS | nonce | counter ], where:
        //   FLAGS is 1 byte long
        //   nonce is 13 bytes long
        //   counter is 2 bytes long
        // The byte FLAGS is composed by the following 8 bits:
        //   0-2 bits: used to represent the value of q-1
        //   3-7 bits: always 0's
        let mut b = [0u8; AES_BLOCK_SIZE];
        let mut tag = [0u8; AES_BLOCK_SIZE];

        // Generating the authentication tag ----------------------------------

        // Formatting the sequence b for authentication
        b[0] = if alen > 0 { 0x40 } else { 0 }
            | ((self.mlen as u8 - 2) / 2) << 3
            | 1;
        b[1..14].copy_from_slice(&self.nonce[..13]);
        b[14] = (plen >> 8) as u8;
        b[15] = plen as u8;

        // Computing the authentication tag using CBC-MAC
        tag.copy_from_slice(&b);
        self.cipher
            .encrypt_block(GenericArray::from_mut_slice(&mut tag));
        if alen > 0 {
            ccm_cbc_mac(&mut tag, associated_data, true, &self.cipher);
        }
        if plen > 0 {
            ccm_cbc_mac(&mut tag, payload, false, &self.cipher);
        }

        // Encryption ---------------------------------------------------------

        // Formatting the sequence b for encryption
        // q - 1 = 2 - 1 = 1
        b[0] = 1;
        b[14] = 0;
        b[15] = 0;

        // Encrypting payload using ctr mode
        ccm_ctr_mode(&mut out[..plen], payload, &mut b, &self.cipher);

        // Restoring initial counter for ctr_mode (0)
        b[14] = 0;
        b[15] = 0;

        // Encrypting b and adding the tag to the output
        self.cipher
            .encrypt_block(GenericArray::from_mut_slice(&mut b));
        for i in 0..self.mlen {
            out[plen + i] = tag[i] ^ b[i];
        }

        Ok(&mut out[..plen + self.mlen])
    }
/// CCM tag generation and encryption procedure.
///
/// `out` buffer must be at least (`payload.len()` + `c.mlen`) bytes long.
/// A slice to the encrypted output within the buffer will be returned.
CCM tag generation and encryption procedure.
CCM tag generation and encryption procedure .
pub fn generate_encrypt<'a>(
        &self,
        out: &'a mut [u8],
        associated_data: &[u8],
        payload: &[u8],
    ) -> Result<&'a [u8], Error> {
        let olen = out.len();
        let alen = associated_data.len();
        let plen = payload.len();
        // Input sanity check
        if alen >= CCM_AAD_MAX_BYTES || plen >= CCM_PAYLOAD_MAX_BYTES {
            return Err(Error::UnsupportedSize);
        }
        if olen < plen + self.mlen {
            return Err(Error::InvalidOutSize);
        }
        // The sequence b for encryption is formatted as follows:
        // b = [FLAGS | nonce | counter ], where:
        //   FLAGS is 1 byte long
        //   nonce is 13 bytes long
        //   counter is 2 bytes long
        // The byte FLAGS is composed by the following 8 bits:
        //   0-2 bits: used to represent the value of q-1
        //   3-7 bits: always 0's
        let mut b = [0u8; AES_BLOCK_SIZE];
        let mut tag = [0u8; AES_BLOCK_SIZE];
        // Generating the authentication tag ----------------------------------
        // Formatting the sequence b for authentication
        b[0] = if alen > 0 { 0x40 } else { 0 }
            | ((self.mlen as u8 - 2) / 2) << 3
            | 1;
        b[1..14].copy_from_slice(&self.nonce[..13]);
        b[14] = (plen >> 8) as u8;
        b[15] = plen as u8;
        // Computing the authentication tag using CBC-MAC
        tag.copy_from_slice(&b);
        self.cipher
            .encrypt_block(GenericArray::from_mut_slice(&mut tag));
        if alen > 0 {
            ccm_cbc_mac(&mut tag, associated_data, true, &self.cipher);
        }
        if plen > 0 {
            ccm_cbc_mac(&mut tag, payload, false, &self.cipher);
        }
        // Encryption ---------------------------------------------------------
        // Formatting the sequence b for encryption
        // q - 1 = 2 - 1 = 1
        b[0] = 1;
        b[14] = 0;
        b[15] = 0;
        // Encrypting payload using ctr mode
        ccm_ctr_mode(&mut out[..plen], payload, &mut b, &self.cipher);
        // Restoring initial counter for ctr_mode (0)
        b[14] = 0;
        b[15] = 0;
        // Encrypting b and adding the tag to the output
        self.cipher
            .encrypt_block(GenericArray::from_mut_slice(&mut b));
        for i in 0..self.mlen {
            out[plen + i] = tag[i] ^ b[i];
        }
        Ok(&mut out[..plen + self.mlen])
    }
pub fn generate_encrypt < ' a > ( & self , out : & ' a mut [ u8 ] , associated_data : & [ u8 ] , payload : & [ u8 ] , ) -> Result < & ' a [ u8 ] , Error > { let olen = out . len ( ) ; let alen = associated_data . len ( ) ; let plen = payload . len ( ) ; // Input sanity check if alen >= CCM_AAD_MAX_BYTES || plen >= CCM_PAYLOAD_MAX_BYTES { return Err ( Error :: UnsupportedSize ) ; } if olen < plen + self . mlen { return Err ( Error :: InvalidOutSize ) ; } // The sequence b for encryption is formatted as follows: // b = [FLAGS | nonce | counter ], where: //   FLAGS is 1 byte long //   nonce is 13 bytes long //   counter is 2 bytes long // The byte FLAGS is composed by the following 8 bits: //   0-2 bits: used to represent the value of q-1 //   3-7 bits: always 0's let mut b = [ 0u8 ; AES_BLOCK_SIZE ] ; let mut tag = [ 0u8 ; AES_BLOCK_SIZE ] ; // Generating the authentication tag ---------------------------------- // Formatting the sequence b for authentication b [ 0 ] = if alen > 0 { 0x40 } else { 0 } | ( ( self . mlen as u8 - 2 ) / 2 ) << 3 | 1 ; b [ 1 .. 14 ] . copy_from_slice ( & self . nonce [ .. 13 ] ) ; b [ 14 ] = ( plen >> 8 ) as u8 ; b [ 15 ] = plen as u8 ; // Computing the authentication tag using CBC-MAC tag . copy_from_slice ( & b ) ; self . cipher . encrypt_block ( GenericArray :: from_mut_slice ( & mut tag ) ) ; if alen > 0 { ccm_cbc_mac ( & mut tag , associated_data , true , & self . cipher ) ; } if plen > 0 { ccm_cbc_mac ( & mut tag , payload , false , & self . cipher ) ; } // Encryption --------------------------------------------------------- // Formatting the sequence b for encryption // q - 1 = 2 - 1 = 1 b [ 0 ] = 1 ; b [ 14 ] = 0 ; b [ 15 ] = 0 ; // Encrypting payload using ctr mode ccm_ctr_mode ( & mut out [ .. plen ] , payload , & mut b , & self . cipher ) ; // Restoring initial counter for ctr_mode (0) b [ 14 ] = 0 ; b [ 15 ] = 0 ; // Encrypting b and adding the tag to the output self . cipher . encrypt_block ( GenericArray :: from_mut_slice ( & mut b ) ) ; for i in 0 .. self . mlen { out [ plen + i ] = tag [ i ] ^ b [ i ] ; } Ok ( & mut out [ .. plen + self . mlen ] ) }
CCM tag generation and encryption procedure.
CCM tag generation and encryption procedure .
&self
out
&'a mut [u8]
associated_data
&[u8]
payload
&[u8]
&self
out
&'a mut [u8]
associated_data
&[u8]
payload
&[u8]