How to Verify the Digital Signature of a SLIC Table

Discussion in 'BIOS Mods' started by crypto, Aug 4, 2009.

  1. crypto

    crypto MDL Member

    Nov 3, 2008
    114
    381
    10
    #1 crypto, Aug 4, 2009
    Last edited by a moderator: Apr 20, 2017
  2. zort

    zort MDL Expert

    Feb 19, 2008
    1,105
    18
    60
    Thanks for this guide, crypto!
     
  3. frwil

    frwil MDL Addicted

    Sep 22, 2008
    541
    195
    30
    Interesting topic. Wish there were command-line tools like that calculator...
    I think there's a similar way to verify xrm-ms files, and oem-certificates as an example. <DigestValue> is what they sign and it is SHA1 of yet unsigned license (without enveloped <Signature> elements).
     
  4. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
    I wish i have known a way to calculate "s^e mod n" in ASP/VBScript :)
     
  5. justinkb

    justinkb MDL Member

    Jul 16, 2008
    193
    9
    10
    i dont know vb.net but (s^e) Mod n should work, otherwise try Math.Pow(s,e) Mod n
    thanks for this guide :)
     
  6. frwil

    frwil MDL Addicted

    Sep 22, 2008
    541
    195
    30
    Thank you for the tips. If possible please could you provide an example with manual verification of Asus oem certificate? And more detailed how to do it with the tool in your previous post.
     
  7. ionsmurf

    ionsmurf MDL Novice

    Jul 6, 2009
    6
    0
    0
    The code posted earlier is more sample code. Here is a bit more of a tool.
    Usage: CertInfo "path to certificate" e.g. CertInfo "ASUS.XRM-MS"
     
  8. frwil

    frwil MDL Addicted

    Sep 22, 2008
    541
    195
    30
    Thank you again!
    And your previous command-line tool:
     
  9. str8

    str8 MDL Expert

    Jul 3, 2009
    1,506
    56
    60
    crypto thank you VERY much for this interesting and valuable information. This should be a "sticky".
     
  10. crypto

    crypto MDL Member

    Nov 3, 2008
    114
    381
    10
    #15 crypto, Aug 20, 2009
    Last edited by a moderator: May 23, 2017
    (OP)
  11. elffin

    elffin MDL Novice

    Sep 12, 2009
    3
    0
    0
    Thanks very much for your explaination.
    Some questions :
    Where did you get the name(description) of these segments ? I searched but could not find other materials. Are there official documents about this?
    if 0xC8 ~ 0xCB is called Windows Marker Version, what is its meaning (or function) ?
    How about 0xE2 ~ 0xE5, I think this part defines the SLIC version. ( It is 01 00 02 00 in SLIC2.1 ) what is its name ?

    Thanks again!
     
  12. crypto

    crypto MDL Member

    Nov 3, 2008
    114
    381
    10
    #18 crypto, Sep 15, 2009
    Last edited by a moderator: Apr 20, 2017
    (OP)
  13. chaiilee

    chaiilee MDL Novice

    Oct 8, 2009
    37
    0
    0
    I agree, @crypto all of your threads are awsome!
     
  14. MasterDisaster

    MasterDisaster MDL Expert

    Aug 29, 2009
    1,256
    674
    60
    #20 MasterDisaster, Nov 16, 2009
    Last edited by a moderator: Apr 20, 2017
    C# functions to verify SLIC bin and OEM Certificate

    Great tutorial crypto :)
    Was able to write this function by just following your instructions.

    Code:
    
    using System;
    using System.IO;
    using System.Security.Cryptography;
    
    /// <summary>
    /// Verifies the Digital Signature in the SLIC Table
    /// </summary>
    /// <param name="path">Path to the bin file</param>
    /// <returns>true if 'signature' matches the signature computed using the specified hash algorithm and key on 'messageHash'; otherwise, false.</returns>
    
    public bool VerifySign(string path)
    {
        byte[] bin = File.ReadAllBytes(path);
        byte[] exponent = new byte[4];
        byte[] modulus = new byte[128];
        byte[] message = new byte[46];
        byte[] signature = new byte[128];
        Array.Copy(bin, 0x3C, exponent, 0, exponent.Length);
        Array.Copy(bin, 0x40, modulus, 0, modulus.Length);
        Array.Copy(bin, 0xC8, message, 0, message.Length);
        Array.Copy(bin, 0xF6, signature, 0, signature.Length);
        Array.Reverse(exponent);
        Array.Reverse(modulus);
        RSAParameters parameter = new RSAParameters();
        parameter.Exponent = exponent;
        parameter.Modulus = modulus;
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSA.ImportParameters(parameter);
        RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA);
        RSADeformatter.SetHashAlgorithm("SHA256");
        byte[] messageHash = new SHA256Managed().ComputeHash(message);
        return RSADeformatter.VerifySignature(messageHash, signature);
    }
    
    Function to verify integrity of signature and license info in certificate.

    Code:
    using System;
    using System.Text;
    using System.IO;
    using System.Security.Cryptography;
    using System.Security.Cryptography.Xml;
    using System.Xml;
    
    /// <summary>
    /// Verifies the Signature and Licence Info in the Certificate
    /// </summary>
    /// <param name="path">Path to the certificate file</param>
    /// <returns>true if 'sign' matches the signature computed using the specified hash algorithm and key on 'Signature' and 'Digest' matches the computed hash for license; otherwise, false.</returns>
    
    public bool VerifyCert(string path)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(path);
        XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
        transform.LoadInput(new MemoryStream(Encoding.UTF8.GetBytes(doc.GetElementsByTagName("SignedInfo")[0].OuterXml)));
        byte[] siHash = transform.GetDigestedOutput(SHA1.Create());
        byte[] Signature = Convert.FromBase64String(doc.GetElementsByTagName("SignatureValue")[0].InnerText);
        byte[] Modulus = Convert.FromBase64String(doc.GetElementsByTagName("Modulus")[0].InnerText);
        byte[] Exponent = Convert.FromBase64String(doc.GetElementsByTagName("Exponent")[0].InnerText);
        string Digest = doc.GetElementsByTagName("DigestValue")[0].InnerText;
        RSAParameters parameter = new RSAParameters();
        parameter.Modulus = Modulus;
        parameter.Exponent = Exponent;
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.ImportParameters(parameter);
        RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
        rsaDeformatter.SetHashAlgorithm("SHA1");
        bool sign = rsaDeformatter.VerifySignature(siHash, Signature);
        XmlLicenseTransform License = new XmlLicenseTransform();
        License.Context = (XmlElement)doc.GetElementsByTagName("Signature")[0];
        License.LoadInput(doc);
        transform = new XmlDsigC14NTransform();
        transform.LoadInput(License.GetOutput());
        string dvHash = Convert.ToBase64String(transform.GetDigestedOutput(SHA1.Create()));
        return sign && dvHash.Equals(Digest);
    }
    
    Function to compare Certificate data with SLIC Table.

    Code:
    using System;
    using System.IO;
    using System.Xml;
    
    /// <summary>
    /// Compare Certificate data and SLIC Table
    /// </summary>
    /// <param name="binFile">Path to bin file</param>
    /// <param name="certFile">Path to certificate file</param>
    /// <returns>true if data matches; otherwise false.</returns>
    
    public bool Compare(string binFile, string certFile)
    {
        byte[] bin = File.ReadAllBytes(binFile);
        XmlDocument doc = new XmlDocument();
        doc.Load(certFile);
        byte[] cert = Convert.FromBase64String(doc.GetElementsByTagName("sl:data")[0].InnerText);
        int i = 0;
        int j = 0;
        bool match = cert.Length == cert;
        for (i = 4, j = 0xC8; i < 14; i++, j++)
            match &= cert == bin[j];
        for (j = 0x3C; i < cert.Length; i++, j++)
            match &= cert == bin[j];
        return match;
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...