@@ -6001,6 +6001,174 @@ VOID
60016001SYMCRYPT_CALL
60026002SymCryptXtsAesSelftest (void );
60036003
6004+ ////////////////////////////////////////////////////////////////////////////////////////////
6005+ //
6006+ // AES-KW and AES-KWP
6007+ //
6008+ // These are the AES-KW and AES-KWP algorithms per SP 800-38F.
6009+ //
6010+ // These are very slow compared to most AES modes, requiring a long serial chain of AES
6011+ // block encryption/decryptions, with a best case cost comparable to ~12x AES-CBC encryption
6012+ // for a given buffer size. In practice the cost is often higher.
6013+ // These cipher modes are not recommended.
6014+ //
6015+
6016+ SYMCRYPT_ERROR
6017+ SYMCRYPT_CALL
6018+ SymCryptAesKwEncrypt (
6019+ _In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey ,
6020+ _In_reads_ (cbSrc ) PCBYTE pbSrc ,
6021+ SIZE_T cbSrc ,
6022+ _Out_writes_to_ (cbDst , * pcbResult ) PBYTE pbDst ,
6023+ SIZE_T cbDst ,
6024+ _Out_ SIZE_T * pcbResult );
6025+ //
6026+ // Encrypt a buffer using AES-KW mode.
6027+ //
6028+ // - pExpandedKey points to the expanded key to use.
6029+ // - pbSrc is the plaintext source buffer. The source and destination buffers may be
6030+ // identical (in-place encryption) or non-overlapping, but they may not partially overlap.
6031+ // - cbSrc. # bytes of plaintext. This must be a multiple of 8, >=16, and <2^31.
6032+ // - pbDst is the ciphertext destination buffer. The source and destination buffers may be
6033+ // identical (in-place encryption) or non-overlapping, but they may not partially overlap.
6034+ // - cbDst. # bytes in the destination buffer. This must be >= cbSrc+8.
6035+ // - pcbResult pointer to a variable which receives the length of the ciphertext written to pbDst.
6036+ //
6037+ // Returns:
6038+ // SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size
6039+ // SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough
6040+ // (this can always be avoided if cbDst >= cbSrc+8)
6041+ // SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation
6042+ // SYMCRYPT_NO_ERROR : On success
6043+ //
6044+ // Remarks:
6045+ // The standard allows larger plaintexts but there is no requirement to support them, we only support
6046+ // plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and
6047+ // is larger than practically necessary.
6048+ // The output parameters (pbDst and pcbResult) are only set on success.
6049+ //
6050+
6051+ SYMCRYPT_ERROR
6052+ SYMCRYPT_CALL
6053+ SymCryptAesKwDecrypt (
6054+ _In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey ,
6055+ _In_reads_ (cbSrc ) PCBYTE pbSrc ,
6056+ SIZE_T cbSrc ,
6057+ _Out_writes_to_ (cbDst , * pcbResult ) PBYTE pbDst ,
6058+ SIZE_T cbDst ,
6059+ _Out_ SIZE_T * pcbResult );
6060+ //
6061+ // Decrypt a buffer using AES-KW mode.
6062+ //
6063+ // - pExpandedKey points to the expanded key to use.
6064+ // - pbSrc is the ciphertext source buffer. The source and destination buffers may be
6065+ // identical (in-place decryption) or non-overlapping, but they may not partially overlap.
6066+ // - cbSrc. # bytes of ciphertext. This must be a multiple of 8, >=24, and <=2^31.
6067+ // - pbDst is the plaintext destination buffer. The source and destination buffers may be
6068+ // identical (in-place decryption) or non-overlapping, but they may not partially overlap.
6069+ // - cbDst. # bytes in the destination buffer. This must be >= cbSrc-8.
6070+ // - pcbResult pointer to a variable which receives the length of the plaintext written to pbDst.
6071+ //
6072+ // Returns:
6073+ // SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size
6074+ // SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough
6075+ // (this can always be avoided if cbDst >= cbSrc-8)
6076+ // SYMCRYPT_AUTHENTICATION_FAILURE : If pbSrc does not decrypt successfully
6077+ // SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation
6078+ // SYMCRYPT_NO_ERROR : On success
6079+ //
6080+ // Remarks:
6081+ // The standard allows larger plaintexts but there is no requirement to support them, we only support
6082+ // plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and
6083+ // is larger than practically necessary.
6084+ // The output parameters (pbDst and pcbResult) are only set on success.
6085+ //
6086+
6087+ SYMCRYPT_ERROR
6088+ SYMCRYPT_CALL
6089+ SymCryptAesKwpEncrypt (
6090+ _In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey ,
6091+ _In_reads_ (cbSrc ) PCBYTE pbSrc ,
6092+ SIZE_T cbSrc ,
6093+ _Out_writes_to_ (cbDst , * pcbResult ) PBYTE pbDst ,
6094+ SIZE_T cbDst ,
6095+ _Out_ SIZE_T * pcbResult );
6096+ //
6097+ // Encrypt a buffer using AES-KWP mode.
6098+ //
6099+ // - pExpandedKey points to the expanded key to use.
6100+ // - pbSrc is the plaintext source buffer. The source and destination buffers may be
6101+ // identical (in-place encryption) or non-overlapping, but they may not partially overlap.
6102+ // - cbSrc. # bytes of plaintext. This must be >0 and <=2^31-8.
6103+ // - pbDst is the ciphertext destination buffer. The source and destination buffers may be
6104+ // identical (in-place encryption) or non-overlapping, but they may not partially overlap.
6105+ // - cbDst. # bytes in the destination buffer. This must be >= cbSrc + 16 - (cbSrc%8) - ((cbSrc%8)==0 ? 8 : 0)
6106+ // - pcbResult pointer to a variable which receives the length of the ciphertext written to pbDst.
6107+ //
6108+ // Returns:
6109+ // SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size
6110+ // SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough
6111+ // (this can always be avoided if cbDst >= cbSrc+15)
6112+ // SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation
6113+ // SYMCRYPT_NO_ERROR : On success
6114+ //
6115+ // Remarks:
6116+ // The standard allows larger plaintexts but there is no requirement to support them, we only support
6117+ // plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and
6118+ // is larger than practically necessary.
6119+ // The output parameters (pbDst and pcbResult) are only set on success.
6120+ //
6121+
6122+ SYMCRYPT_ERROR
6123+ SYMCRYPT_CALL
6124+ SymCryptAesKwpDecrypt (
6125+ _In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey ,
6126+ _In_reads_ (cbSrc ) PCBYTE pbSrc ,
6127+ SIZE_T cbSrc ,
6128+ _Out_writes_to_ (cbDst , * pcbResult ) PBYTE pbDst ,
6129+ SIZE_T cbDst ,
6130+ _Out_ SIZE_T * pcbResult );
6131+ //
6132+ // Decrypt a buffer using AES-KWP mode.
6133+ //
6134+ // - pExpandedKey points to the expanded key to use.
6135+ // - pbSrc is the ciphertext source buffer. The source and destination buffers may be
6136+ // identical (in-place decryption) or non-overlapping, but they may not partially overlap.
6137+ // - cbSrc. # bytes of ciphertext. This must be a multiple of 8, >=16, and <=2^31.
6138+ // - pbDst is the plaintext destination buffer. The source and destination buffers may be
6139+ // identical (in-place decryption) or non-overlapping, but they may not partially overlap.
6140+ // - cbDst. # bytes in the destination buffer. This must be large enough to fit the plaintext,
6141+ // a valid plaintext length is in the range [cbSrc-15, cbSrc-8]. If cbDst >= cbSrc-8 then the
6142+ // destination buffer is guaranteed to be large enough.
6143+ // - pcbResult pointer to a variable which receives the length of the plaintext written to pbDst.
6144+ //
6145+ // Returns:
6146+ // SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size
6147+ // SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough
6148+ // (this can always be avoided if cbDst >= cbSrc-8)
6149+ // SYMCRYPT_AUTHENTICATION_FAILURE : If pbSrc does not decrypt successfully
6150+ // SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation
6151+ // SYMCRYPT_NO_ERROR : On success
6152+ //
6153+ // Remarks:
6154+ // The standard allows larger plaintexts but there is no requirement to support them, we only support
6155+ // plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and
6156+ // is larger than practically necessary.
6157+ // The output parameters (pbDst and pcbResult) are only set on success.
6158+ //
6159+ // If we fail to decrypt due to bad data, we return SYMCRYPT_AUTHENTICATION_FAILURE in constant time with
6160+ // respect to how the decrypted data is corrupted. While there is no known attack on AES-KWP abusing
6161+ // differential timing of different failure cases, being constant time for this is cheap, so is a reasonable
6162+ // hardening measure.
6163+ //
6164+ // On success we do not attempt to hide the plaintext length from sidechannels, as this could make it hard
6165+ // for callers with known plaintext length to use precisely sized buffers to decrypt into (i.e. caller
6166+ // knows the valid plaintext is 15 bytes but the API would require caller to provide a 16 byte pbDst). It
6167+ // is expected that in any real use case the length of the plaintext would immediately be used to import the
6168+ // unwrapped key into some other piece of code - so attempting to obscure the plaintext length would not be
6169+ // of any benefit.
6170+ //
6171+
60046172
60056173////////////////////////////////////////////////////////////////////////////////////////////
60066174//
0 commit comments