Near in place encryption with BouncyCastle CCM, How large must IV and MAC be? I need to encrypt 20 bytes of data and the encrypted nonce + data + mac cannot exceed 30 bytes in size. I have an implementation but i'm not sure if i'm cutting too many corners and compromising encryption.

Using the bouncy castle library i was able to write this.

    static (byte[],byte[]) encrypt(byte[] data, byte[] key, byte[] nonce)
    {
        var engine = new AesEngine();
        var parm = new AeadParameters(new KeyParameter(key), 16, nonce);
        var chipher = new CcmBlockCipher(engine);
        chipher.Init(true, parm);

        var output = new byte[chipher.GetOutputSize(data.Length)];
        var outputLength = chipher.ProcessBytes(data, 0, data.Length, output, 0);
        chipher.DoFinal(output, outputLength);

        return (output, chipher.GetMac());
    }


Here is my thinking. For the data encrypted i have the following pieces of information known:


Metadata about the origination of the data 
The approximate date the data was encrypted (down to the day)


With that information i formulated a nonce that contains:

2 bytes meta + 8 bytes Unix ms timestamp


With that i'm able to chop off all but the last 4 bytes of the nonce as those are the least significant bytes that indicate a timestamp for the day in question. 

With that in mind i can have the final full encoded data as:

4 byte nonce + 20 byte encrypted + 2 byte MAC


This makes it fit under the 30 byte limit. 

So here are my questions:


Is a 16 bit MAC effective at all in this scenario?
Is it kosher to create a nonce from partially known data?
How can i verify that my nonce is being incremented properly inside the code? I just appear to pass a static nonce even though its supposed to increment according to CTR... right?
So I'll answer in order:


  Q1: Is a 16 bit MAC effective at all in this scenario?


You have defined (part of) your protocol, but you haven't defined your system. What happens if a MAC doesn't get accepted? If you have only a 16 bit MAC then there are only 65536 values of the MAC. If an adversary can just generate messages and fire them at the receiver then brute forcing a tag is entirely possible. Even if you can just have one try: a chance of $1 \over 65536$ is not considered secure enough.

Using 8 bytes would be a great idea, but that leaves you only 2 bytes for a nonce, so you would only have 65536 messages.


  Q2: Is it kosher to create a nonce from partially known data?


Sure thing, a Nonce just needs to be unique - but note that in the case of CTR and CCM the nonce size also influences how many counter blocks can be created, and therefore how much data can be processed per nonce. CCM is just like CTR in that sense; it even requires an additional byte of meta information in the counter, leaving less space for the nonce and counter.

Kind of obvious, but the other requirement is that the receiver must be able to re-generate the nonce.


  Q3: How can i verify that my nonce is being incremented properly inside the code? I just appear to pass a static nonce even though its supposed to increment according to CTR... right?


No, the counter is being incremented - not the nonce. The nonce is just used to create the counter. Often the nonce is simply the most significant part of the counter. In the case of CCM this is true as well, even though the most significant byte is skipped. see for instance NIST SP 800-38C chapter A.3 where the counter increase is being implemented.

In GCM mode it is also possible that the nonce is pre-processed to generate the initial counter value, so there are certainly differences in how the nonce is used between the various implementations of authenticated encryption, even though CTR mode is used in virtually all these modes.

Note that the counter mode specified by NIST does not specify how the counter value must be generated; implementations are free to choose any scheme they want.