
USE master
GO

CREATE FUNCTION dbo.CalculateCipherLen( 
  @KeyName sysname, @PTLen int, @UsesHash	int = 0 )
RETURNS int
as
BEGIN
  declare @KeyType	nvarchar(2)
  declare @RetVal int
  declare @BLOCK int
  declare @IS_BLOCK	int
  declare @HASHLEN	int
	
  -- Hash length that
  SET @HASHLEN	= 20
  SET @RetVal	= NULL
  -- Look for the symmetric key in the catalog 
  SELECT @KeyType	= key_algorithm 
    FROM sys.symmetric_keys WHERE name = @KeyName
	
  -- If parameters are valid
  IF( @KeyType is not null AND @PTLen > 0)
    BEGIN
	-- If hash is being used. NOTE: as we use this value to
      -- calculate the length, we only use 0 or 1
  IF( @UsesHash <> 0 ) SET @UsesHash = 1
	
  -- 64 bit block ciphers
  IF( @KeyType = N'R2' OR @KeyType = N'D' 
      OR @KeyType = N'D3' OR @KeyType = N'DX' )
    BEGIN
      SET @BLOCK = 8
	SET @IS_BLOCK	= 1
    END
  -- 128 bit block ciphers
  ELSE IF( @KeyType = N'A1' OR @KeyType = N'A2' OR @KeyType = N'A3' )
    BEGIN
      SET @BLOCK = 16
SET @IS_BLOCK	= 1
    END
    -- Stream ciphers, only RC4 is supported as a stream cipher
    ELSE
	BEGIN
	  SET @IS_BLOCK	= 0
	END
	
    -- Calclulate the expected length. 
    -- The formula is different for block ciphres & stream ciphers
    IF( @IS_BLOCK = 1 )
	BEGIN
	SET @RetVal = 
        ( FLOOR( (8 + @PTLen + (@UsesHash * @HASHLEN) )/@BLOCK)+1 ) *    
          @BLOCK + 16 + @BLOCK
	END
	ELSE
  BEGIN
		SET @RetVal = @PTLen + (@UsesHash * @HASHLEN) + 28
	  END
	END
	RETURN @RetVal
END
GO
