Specification of Encryption for Valentina 2.0

Ruslan Zasukhin sunshine at public.kherson.ua
Sun Jul 31 18:55:45 CDT 2005


/***************************************************************************
***/
Specification (point of user)

* User can encrypt
    - the whole database.
    - one or few tables.
    - one or few fields.

* User cannot encrypt links.
    Valentina 2.0 have Binary Links. But since they keep only values of
RecIDs
    there is no sense to encrypt them.
                  
* Hierarchy of objects
        VDatabase -> VTable -> VField

    inherit settings of encryption parameters. In other words, if user
    have encrypt database, then each its table also is encrypted using the
    same password. And each field of a table also is encrypted by that
password.

* User cannot assign password to an object if its supervisor already is
encrypted.
    We do not want do this to avoid ambigiouty with passwords.
    
    In case user try to assign password to a such object, then user get
ERROR
            "This object already is encrypted"
        
* Note that the main job do VField. VDatabase and VTable objects play just a
role of 
    password-keeper. So VField encrypt data stored in column of Table, also
    indexes of the field is encrypted.

* If user forget password then big problems. Because nobody can decrypt that
database.

* Each of classes VDatabase, VTable and VField implements interface
I_Encryptable.    

* Important to note that you should never try read data that are encrypted
until
    you specify correct password. So first of all you must check that you do
not
    get error WRONG_PASSWORD, and only after this try to read data.

* What happens if user try read data without password? Hard to say...
    He can see garbage, or may be NULLs or may be empty strings.
    In ideal system must not crash on access to such non-encrypted data,
    although it seems it is hard to implement this.


/***************************************************************************
***/
* Interface I_Encryptable offer to user the next operations:

// Properties:

    // -----------------------------------------------------------------
    IsEncrypted : bool

        DESCRIPTION: Returns TRUE if this object is encrypted,
            never mind how -- directly or by supervisor.


    // -----------------------------------------------------------------
    RequirePassword : bool

        DESCRIPTION: Returns TRUE if this object is root of encryption,
            and user must specify password to get access to data of this
object
            and all its sub-objects.


// Group of methods to encrypt/decrypt:

    // -----------------------------------------------------------------
    Encrypt( inPassword: string ) : void

        DESCRIPTION: Encrypt object using the specified password.

        ERRORS:     - "Object already is encrypted."
                    - "Object already is encrypted by supervisor."

        First error happens if user try encrypt
        already encrypted db for example.

        Second error when user try encrypt e.g.
        Table but its daatabse already is encrypted.


    // -----------------------------------------------------------------
    Decrypt( inPassword: string ) : void
    
        DESCRIPTION: Removes encryption for an object.

        ERRORS:     - "Object is not encrypted."
                    - "Object is encrypted by supervisor."
                   

    // -----------------------------------------------------------------
    ChangePassword( inOldPassword : string, inNewPassword : string ) : void
    
        DESCRIPTION: Changes password of encryption for an object.

        ERRORS:     - "Object is not encrypted."
                    - "Object is encrypted by supervisor."
                    - "Wrong password."

                   
// Group of methods to get access to encrypted objects

    // -----------------------------------------------------------------
    UsePassword( inPassword : string ) : void
                   
        DESCRIPTION: Informs object by the password that it must use to
decrypt
            data when read them from database files.
            
            In case user specifies a wrong password the error will be thrown
with 
            the delay in one second to prevent hacking.

        ERRORS:     - "Object is not encrypted."
                    - "Wrong password."
            
        Errors are returned only if you apply this to Table or Field,
        i.e. database already is opened. When you apply this to a closed
database    
        then error cannot be checked, so error can be faired on db.Open().


/***************************************************************************
***/
Technical notes of implementation.

* On default we use BlowFish algorithm. This algorithm require that data are
aligned to 8 bytes.

    Taking into account that Cache pages are 4Kb, we will use this amount of
data
    as atomic set to encrypt/decrypt.

* On disk all files of encrypted objects are ALWAYS encrypted.

* We decrypt page when it is loaded into the Cache.
    Decryption must happens before ByteSwap algorithms start work:
    Cache.Read() -> Decrypt() -> ByteSwap()
    
* When page must go to disk we again encrypt it.
    To encrypt page, we need to use helper buffer of the same size,
    because it is no good encrypt it directly in cache, we still can use it.
    Only optimisation possible if we exactly know that this page is removed
from
    cache right now.

* interface I_Encryptable is visiable only on C++ level.
    All rest plugins do not have it, just classes VDatabase, VTable, VField
    have set of Encryption Methods.

        

/***************************************************************************
***/
Examples of usage:

1.1 Encryption of database (empty of with records):

    db = new VDatabase()
    db.Open()

    db.Encrypt( "password" )
    db.Close()


1.2 Opening of encrypted database:
    
  1.2.1 We know that databse is encrypted
    
    OpenEncrypted( db )
    {
        db.UsePassword( "password" )    -- never produce error
        try    
            db.Open()                    -- can throw error
NOT_ENCRYPTED, WRONG_PASSW
        catch err
    }

  1.2.2 We do not know if this databse is encrypted.

    OpenUnknown( db )
    {
        db = new VDatabase()
        try    
            db.Open()                    -- can throw error WRONG_PASSW
        catch err
            OpenAsEncrypted()
        end
    }


    OpenAsEncrypted()
    {
        // Ask user for a password. E.g. VStudio may need this.
        passw = ...
        
        // then open db using that password:
        OpenEncrypted( passw );
    }


1.3 Decryption of existed encrypted database

    db.Decrypt( "passw" )


1.4. Change of password:

    db.ChangePassword( "passw", "passw2" )



// ----------------------------------------------------
2.1 Database is not encrypted and we want encrypt one table

    db.Open()     -- open without password.

    db.Table( "tblEncrypted" ).Encrypt( "passwtbl" ) -- can throw error.


2.2 Database is not encrypted but one of tables is.

    db.Open()     -- open without password.

    db.Table( "tblEncrypted" ).UsePassword( "passwtbl" ) -- can throw error.


2.3 Remove encryption from single table:

    db.Table( "tblEncrypted" ).Decrypt( "passwtbl" )

-- 
Best regards,

Ruslan Zasukhin
VP Engineering and New Technology
Paradigma Software, Inc

Valentina - Joining Worlds of Information
http://www.paradigmasoft.com

[I feel the need: the need for speed]



More information about the Valentina mailing list