Stony Brook index page Stony Brook Modula-2 archive and support pages

Home - News - Tips & Tricks - Library Fixes - Bugs workarounds - SB site archive

Fixes for the RSA module OAEP decrypt and PSS verify procedures

July 29, 2005

By Norman Black in the comp.lang.modula2 newsgroup.

Fixes for the RSA module OAEP decrypt and PSS verify procedures. They handle the leading zeros issue.

PROCEDURE Decrypt_OAEP_SHA1(crypt : RSA;
                            cipher : ADDRESS;
                            cipherLen : CARDINAL;
                            encodingParams : ADDRESS;
                            encodingParamsLen : CARDINAL;
                            message : ADDRESS;
                            VAR INOUT messageLen : CARDINAL) : BOOLEAN;
VAR
    emLen       : CARDINAL;
    pad         : CARDINAL;
    i           : CARDINAL;
BEGIN
    IF crypt^.sha1  = NIL THEN
        crypt^.sha1 := SHA1.Create();
    END;


    emLen := crypt^.bufSize;
    IF PrivateFunction(crypt,
                       cipher, cipherLen,
                       crypt^.buffer, emLen)
    THEN
        pad := crypt^.emLen-emLen;
        IF pad <> 0 THEN
            MoveMem(ADR(crypt^.buffer^[pad]), crypt^.buffer, emLen);
            i := 0;
            REPEAT
                DEC(pad);
                crypt^.buffer^[i] := 0;
                INC(i);
            UNTIL pad = 0;
        END;
        RETURN Decode_OAEP(crypt^.buffer, crypt^.emLen,
                           encodingParams, encodingParamsLen,
                           message, messageLen,
                           HashFunc_SHA1, crypt^.sha1, SHA1.HashLength);
    END;
    RETURN FALSE;
END Decrypt_OAEP_SHA1;


PROCEDURE Verify_PSS_SHA1(crypt : RSA;
                          cipher : ADDRESS;
                          cipherLen : CARDINAL;
                          saltLen : CARDINAL;
                          messageHash : ADDRESS) : BOOLEAN;
VAR
    emLen       : CARDINAL;
    pad         : CARDINAL;
    i           : CARDINAL;
BEGIN
    IF crypt^.sha1  = NIL THEN
        crypt^.sha1 := SHA1.Create();
    END;


    IF PublicFunction(crypt,
                      cipher, cipherLen,
                      crypt^.buffer, emLen)
    THEN
        pad := crypt^.emLen-emLen;
        IF pad <> 0 THEN
            MoveMem(ADR(crypt^.buffer^[pad]), crypt^.buffer, emLen);
            i := 0;
            REPEAT
                DEC(pad);
                crypt^.buffer^[i] := 0;
                INC(i);
            UNTIL pad = 0;
        END;
        RETURN Verify_PSS(crypt^.buffer, crypt^.emLen,
                          saltLen,
                          messageHash,
                          HashFunc_SHA1, crypt^.sha1, SHA1.HashLength);
    END;


    RETURN FALSE;
END Verify_PSS_SHA1;