Re: (#1) Padding method 0-7 0x00's

I see now that this would be incompatible with current behavior where $decode ignores the padding switch used, but tries to match any of 4 different padding methods.

(#1a) Switch to enforce $decode not ignore switches
(#8) Switch to Skip 8 byte text header

* Suggestion for a new switch which causes $decode to stop trying to guess what to do, based on the content of the 1st block of ciphertext or the content of the last block of decrypted ciphertext, and instead decrypt based on the switches used. For example purposes I'll refer to this switch as 'D'.

* Related suggestion for a new switch which causes $encode to not insert the magic text 'RandomIV' or 'Salted__' in front of the IV or Salt string at the front of encrypted messages. Depending on the usage of the other switches, this switch would cause $decode to behave as if these magic strings actually were inserted in front of the input string, even if the string already begins with 'RandomIV' or 'Salted__' due to choices of the 4th parameter, or the possible result of an encrypted string. For example purposes I'll refer to this switch as 'Q'.

+ The new 'D' switch would cause $decode to check only for 1 type of padding based on usage of the 'pnz' switches, or allows the non-usage of these 3 to check only for the PKCS#7 padding. If $decode used a different padding switch than used by $encode, then no padding would be removed if there was not a match with that specific padding.

+ 'D' would avoid the false matches where $encode applied 'z' padding to these messages but $decode removes 'n' padding if the last character of the message was a codepoint greater than 64 that's a multiple of 64:

Code
//bset &v 8 0 | while ($bvar(&v,0) == 8) { bset -tc &v 1 $str(.,$rand(1,6)) $+ $chr($calc(64*$rand(2,700))) } | echo -a original: = $bvar(&v,1-) | noop $encode(&v,bmcz,key) $decode(&v,bmcz,key) | echo 4 -a decrypted = $bvar(&v,1-)



+ This would also enable the ability to eventually have new padding switches without false matches, such as the suggested 0-7 0x00's that avoids increasing the encrypted string's length by +8 for all messages which are already a length that's a multiple of 8, or would allow something similar to OpenSSL's -nopad switch where no padding is added to a message that either doesn't need it or the user has already padded it themselves.

+ This would also prevent $decode from searching for the magic strings "Salted__" or "RandomIV" unless $decode uses the switches related to them. i.e. $decode would not check for "RandomIV" and use bytes 9-16 as the IV unless 'D' were accompanied by the 'r' switch, and $decode would not check for "Salted__" and use bytes 9-16 as a salt unless 'D' were accompanied by 'c but neither of the 'ir' switches.

* When encrypting, using the new 'Q' switch along with 'cir' or 'cr', would continue storing the 8-byte IV at the front of the header, but 'Q' would prevent inserting the text "RandomIV" preceding that.

+When encrypting, using 'c' or 'cs' without using 'i' or 'r', $encode would continue storing the 8-byte salt at the front of the encrypted string, but also using 'Q' would not insert the text "Salted__" preceding that.

+ When decrypting, using the 'Q' switch would prevent $decode from checking for the magic strings 'Salted__' or 'RandomIV', because 'Q' indicates the magic string needs to be added. Using 'crQ' would behave as if the magic string 'RandomIV' needed to be inserted in front of the inpt string, and using 'cQ' otherwise without 'i' or 'r' would behave as if the magic 'Salted__' needed to be inserted. 'ciQ' would decrypt the entire string using the 4th parameter as the IV, regardless of what the input string looks like.

The 1st 8 bytes of the $1 encrypted string would then be handled as if that was the Salt or IV expected to be following the magic string either being inserted or setting a flag indicating how to handle the remainder of the string differently.

The extra 8 bytes of the magic string at the front are more useful to an eavesdropper than to the people sharing encrypted messages, and it just makes the mime string be an extra dozen or so characters against the server's message limit. It requires a lot of steps for a script to trim then restore them:

Code
//var %msg test string , %key test key | bset -tc &v 1 %msg | noop $encode(&v,bmc,%key) | echo 4 -a $bvar(&v,1-).text with header length $bvar(&v,0) | noop $decode(&v,bm) | bcopy -c &v 1 &v 9 -1 | noop $encode(&v,bm) | var %enc $bvar(&v,1-).text | echo 3 -a %enc without "Salted__" header length $bvar(&v,0) | bset -tc &v2 1 %enc | noop $decode(&v2,bm) | bcopy &v2 9 &v2 1 -1 | bset -t &v2 1 Salted__ | noop $encode(&v2,bm) $decode(&v2,bmc,%key) | echo -a decoded: $bvar(&v2,1-).text



***

* By taking action only as indicated by the switches used by $decode, this also avoids the issue where $decode ignores the 'i' switch when the encrypted string begins with a block matching either of the magic strings 'RandomIV' or 'Salted__'.

In these examples, decoding with the 'wrong' switch still 'works' because it takes action based on the header, ignoring the 'i' 'r' and 's' switches other than generating an error when 's' or 'i' isn't accompanied by parm4.

//var -s %enc $encode(test message,mc ,key) | echo -a $decode(%enc,mcr,key)
//var -s %enc $encode(test message,mcr,key) | echo -a $decode(%enc,mcs,key,saltsalt)

***

However in the rare cases where the encryption creates ciphertext beginning with bytes forming either of the magic strings "RandomIV" or "Salted__", $decode ignores using the 'i' switch except for requiring the parm4 string, and the decryption instead acts based on the first 8 bytes of the string happening to match one of the magic values.

In this 1st example, $decode sees the encrypted string beginning with the bytes forming 'Salted__', so it decodes by ignoring %iv, skipping the 1st 8 bytes of the ciphertext as if a magic header, then uses bytes 9-16 as if a Salt in combo with %key. The decrypted output is now the garbled decryption of the 3rd block and later:

//var -s %key spjbavdk , %iv test_iv , %enc $encode(ODMJuQPFabcdefghtestmsg ,mcli,%key,%iv) | echo -a $decode(%enc,mcli,%key,%iv)

decrypted as: õ°ë?²

In this 2nd example, $decode sees the encrypted string beginning with the bytes forming 'RandomIV', so it decodes by again ignoring %iv, again skipping the 1st 8 bytes of the ciphertext as if a magic header, then uses bytes 9-16 as if the IV in place of the parm4 string used with the 'i' switch while in the absence of using the 'r' switch. The decrypted output then skips decryption of the 1st 16 bytes of the original message:

//var -s %key wohccemg , %iv test_iv , %enc $encode(ZGQQrvQU/\/\/\/\3rdblock,mcli,%key,%iv) | echo -a $decode(%enc,mcli,%key,%iv)

Decrypted as: 3rdblock

However, if you edit any of the 4 %key or %iv strings in both examples, or edit the 1st 8 bytes of either original message, the decryption usually works correctly because the 1st block of ciphertext no longer matches one of the 2 magic strings, and $decode then falls back to using the 'li' switches actually used.

This should avoid messages which cannot be corrected decrypted if they were encrypted with padding switch 'z', or encrypted using 'i' without 'r'.