Signing and Verification Tutorial

The Intel® EPID SDK provides example tools to show you how to use the Intel® EPID SDK APIs. These examples are called signmsg and verifysig.

These examples use the pre-generated data described in Test Data. After you build the SDK, the data is in the _install/epid-sdk/example/data directory. If you don't have genuine issuer material, you can use this data for validation purposes.

You can follow along with the commands used in this tutorial if you first build these examples using the instructions in Building from Source. The tutorial assumes _install/epid-sdk/example is the current directory.

All command lines in this tutorial use posix command line conventions; for other systems, adjust accordingly.

For detailed walkthroughs of the code used in signmsg and verifysig, refer to Walkthroughs of Examples Showing API Usage.

Creating an IntelĀ® EPID Signature of a Given Message

The example application signmsg shows you how to create an Intel® EPID signature of a given message.

What Do You Need to Create a Signature?

To generate a signature, you need the following items:

  • Group public key: You need the group public key to specify which group the member belongs to.
  • Member private key: You need the member private key so that the member can create a signature that corresponds with the group public key.
  • Message: You need the message because the member needs something to sign.
  • Hash algorithm: You need the hash algorithm to encrypt the signature. If you don't specify a hash algorithm, a default hash algorithm is used.
  • Signature based revocation list (SigRL): You need the SigRL so that the member can create non-revoked proofs for each entry on the list. For more information, see In-Depth Explanation of Revocation.
  • Member precomputation blob: The precomputation blob is an optional parameter that you can use to improve performance when generating signatures repeatedly with the same member private key.
  • Basename: A basename is a parameter that is only provided when the member is generating a name based signature. If no basename is specified, a random value is chosen as the basename. For more information, see In-Depth Explanation of Basenames.
  • Random number generator: You need a cryptographically secure random number generator to ensure that signatures generated by the same member with the same message are different. The SDK provides the BitSupplier function prototype that specifies the interface for your random number generator implementation.

Signing Example

The signmsg command can be passed a number of options:

$ ./signmsg -h
Usage: signmsg [OPTION]...
Verify signature was created by group member in good standing

Options:
  --sig=FILE                write signature to FILE (default: sig.dat)
  --msg=MESSAGE             MESSAGE to sign
  --msgfile=FILE            FILE containing message to sign
  --bsn=BASENAME            BASENAME to sign with (default: random)
  --bsnfile=FILE            FILE containing basename to sign with
  --sigrl=FILE              load signature based revocation list from FILE
  --gpubkey=FILE            load group public key from FILE (default: pubkey.bin)
  --mprivkey=FILE           load member private key from FILE (default: mprivkey.dat)
  --mprecmpi=FILE           load pre-computed member data from FILE
  --capubkey=FILE           load IoT Issuing CA public key from FILE (default: cacert.bin)
  --hashalg={SHA-256 | SHA-384 | SHA-512 | SHA-512/256} use specified hash algorithm (default: SHA-512)
  --help                    display this help and exit
  -v, --verbose             print status messages to stdout

To sign a message, a group member in good standing uses the following command:

$ ./signmsg --msg="test0"

The above command signs a message "test0". signmsg uses default options for the group public key, member private key, hash algorithm and IoT Issuing CA public key. All other parameters that are not given are ignored. The command produces a signature file: sig.dat

Verifying an IntelĀ® EPID Signature

The example application verifysig shows you how to verify that a given Intel® EPID signature is produced by a member in good standing.

What Do You Need to Verify a Signature?

To verify a signature, you need the following items:

  • Signature: You need the signature that you want to verify.
  • CA certificate: You need the CA certificate to verify the authenticity of the issuer material before you use it. Depending on how your issuer protects its data, you may not need a CA certificate. For more information on issuer material, refer to Preparing a Device and Test Data.
  • Group certificate: The group certificate comes from the issuer and contains the group public key. You need the group public key to determine if the signature came from a member of this group. The group public key corresponds to the member private key used to generate the signature.
  • Message: In order for verification to succeed, you need to specify the message that was signed.
  • Hash algorithm: In order for verification to succeed, you need to specify the hash algorithm that was used to sign the message. If you don't specify a hash algorithm, a default hash algorithm is used.
  • Group based revocation list (GroupRL): You need the GroupRL to ensure the member does not belong to a revoked group. The GroupRL comes from the issuer.
  • Private key based revocation list (PrivRL): You need the PrivRL to ensure that the member private key has not been revoked. The PrivRL comes from the issuer.
  • Signature based revocation list (SigRL): You need to compare the SigRL with non-revoked proofs from the member to ensure that the member did not create any revoked signaures. The SigRL comes from the issuer.
  • Verifier revocation list: The VerRL is optional. The verifier uses the VerRL to ensure that the member did not create any signatures that were revoked by the verifier. You can only use the VerRL if the signature is a name based signature. The VerRL comes from the verifier. For more information, refer to In-Depth Explanation of Revocation and In-Depth Explanation of Basenames.
  • Verifier precomputation blob: The verifier precomputation blob is optional. You can use the precomputation blob to increase performance when verifying signatures repeatedly with the same group public key.
  • Basename: A basename is a parameter that is only provided in instances where Intel® EPID uses name based signatures. If a basename is used, the member and verifier have to use the same basename. If a basename is not specified, a random number is chosen as the basename. Because name-based signatures decrease the member's privacy, they must only be used with the knowledge and consent of the member. For more information, refer to In-Depth Explanation of Basenames.
  • Precomputation blob: You can optionally provide a precomputation blob to greatly speed up EpidVerifierCreate. If you don't use one, the precomputation blob can be stored for use in a future session to verify membership in the same group using EpidVerifierWritePrecomp.

Verification Example

The verifysig command can be passed a number of options:

$ ./verifysig -h
Usage: verifysig [OPTION]...
Create Intel(R) EPID signature of message

Options:
  --sig=FILE                load signature from FILE (default: sig.dat)
  --msg=MESSAGE             MESSAGE that was signed (default: empty)
  --msgfile=FILE            FILE containing message that was signed
  --bsn=BASENAME            BASENAME used in signature (default: random)
  --bsnfile=FILE            FILE containing basename used in signature
  --privrl=FILE             load private key revocation list from FILE
  --sigrl=FILE              load signature based revocation list from FILE
  --grprl=FILE              load group revocation list from FILE (default: grprl.bin)
  --verifierrl=FILE         load verifier revocation list from FILE
  --gpubkey=FILE            load group public key from FILE (default: pubkey.bin)
  --vprecmpi=FILE           load pre-computed verifier data from FILE
  --vprecmpo=FILE           write pre-computed verifier data to FILE
  --capubkey=FILE           load IoT Issuing CA public key from FILE (default: cacert.bin)
  --hashalg={SHA-256 | SHA-384 | SHA-512 | SHA-512/256} use specified hash algorithm for 2.0 groups (default: SHA-512)
  --help                    display this help and exit
  -v, --verbose             print status messages to stdout

To verify that a signature is from a member in good standing, the verifier uses the following command:

$ ./verifysig --msg="test0"
signature verified successfully

This verifies that the default signature file sig.dat is generated for the message "test0" by a member in good standing. The verifysig example uses default inputs for group public key, hash algorithm, and IoT Issuing CA public key. All other parameters are ignored. The output verifysig: signature verified successfully denotes that the verification is successful.

Parameter Matching Requirements

To successfully create and verify a signature, the member and verifier have to use the same message, hash algorithm, signature revocation list, and basename.

The signature verification process fails if there is a parameter mismatch between sign and verify operations. The mechanism for avoiding a parameter mismatch is outside the scope of the SDK.

Message

The member needs the message to generate the signature using the member private key. In order for verification to succeed, the verifier needs to use the same message that the member used.

This comparison allows the verifier to determine if the signature fulfills the verifier's basic expectations of what a signature from a valid member should look like, given the original message and the group public key.

Verification fails if the signing and verification operations don't use the same message:

$ ./signmsg --msg="test0"
$ ./verifysig --msg="test1"
verifysig: signature verification failed: invalid signature

Hash Algorithm

The member needs to encrypt the signature with the hash algorithm. The verifier needs to use the same hash algorithm that the member used.

If you don't specify a hash algorithm, a default hash algorithm is used.

The Intel® EPID SDK supports the following hash algorithms: SHA-256, SHA-384, SHA-512.

Verification fails if the signing and verification operations don't use the same hash algorithm:

$ ./signmsg --msg="test0" --hashalg=SHA-256
$ ./verifysig --msg="test0" --hashalg=SHA-384
verifysig: signature verification failed: invalid signature

Signature Revocation List

The member needs the signature based revocation list (SigRL) to create non-revoked proofs for each entry on the SigRL. The verifier needs to use the same SigRL to check the proofs.

Verification fails if the signing and verification operations don't use the same SigRL.

$ ./signmsg --msg="test0" --sigrl=data\groupa\sigrl.bin
$ ./verifysig --msg="test0" --sigrl=sigrl.bin
verifysig: signature verification failed: bad arguments

Basenames

For a verifier to be able to know that multiple signatures were generated by the same member, the verifier has to use the same basename that the member used for each name based signature. For more information, refer to In-Depth Explanation of Basenames.

If a basename is not provided to the member, then the member uses a random basename and the signature generated by the member is anonymous.

If a basename is not provided to the verifier, then the verifier does not check for a basename and it will verify the signature successfully without linking it to other signatures.

To sign message "test0" with a basename "base0":

$ ./signmsg --msg="test0" --bsn="base0"

To verify the signature:

$ ./verifysig --msg="test0" --bsn="base0"
verifysig: signature verified successfully

Verification fails if the signing and verification operations use different basenames:

$ ./signmsg --msg="test0" --bsn="base0"
$ ./verifysig --msg="test0" --bsn="base1"
verifysig: signature verification failed: invalid signature
Warning
The use of a name-based signature creates a platform unique pseudonymous identifier. Because it reduces the member's privacy, the user should be notified when it is used and should have control over its use.

Revocation

Revocation lists are data structures used by the verifier to identify members that are no longer approved members of the group.

The verifier obtains the member private key based revocation list (PrivRL), signature based revocation list (SigRL), and group based revocation list (GroupRL) from the issuer. The verifier can also maintain its own verifier blacklist (VerifierRL).

Detecting Revoked Group from Group Revocation List

Verification of a signature fails if it is generated by a member of a group that is revoked in the group revocation list.

For example,

$ ./signmsg --msg="test0" --gpubkey=data/groupb/pubkey.bin --mprivkey=data/groupb/member0/mprivkey.dat
$ ./verifysig --msg="test0" --grprl=data/grprl.bin --gpubkey=data/groupb/pubkey.bin
verifysig: signature verification failed: signature revoked in GroupRl

The verification fails because groupb is revoked and is an entry in the group revocation list (grprl.bin).

Detecting Revoked Member from Private Key Based Revocation List

Verification of a signature fails if it is generated by a member whose private key is revoked in a private-key based revocation list.

For example,

$ ./signmsg --msg=test0 --gpubkey=data/groupa/pubkey.bin --mprivkey=data/groupa/privrevokedmember0/mprivkey.dat
$ ./verifysig --msg=test0 --privrl=data/groupa/privrl.bin --gpubkey=data/groupa/pubkey.bin
verifysig: signature verification failed: signature revoked in PrivRl

The verification fails because the private key of privrevokedmember0 is revoked and is an entry in the private key based revocation list of groupa (privrl.bin).

Detecting Revoked Member from Signature Based Revocation List

Verification of a signature fails if it is generated by a member whose signature is revoked in a signature based revocation list.

$ ./signmsg --msg="test1" --sigrl=data/groupa/sigrl.bin --gpubkey=data/groupa/pubkey.bin --mprivkey=data/groupa/sigrevokedmember0/mprivkey.dat
signmsg: signature revoked in SigRL
$ ./verifysig --msg="test1" --sigrl=data/groupa/sigrl.bin --gpubkey=data/groupa/pubkey.bin
verifysig: signature verification failed: signature revoked in SigRl

The message "test1" is signed by signmsg with a warning signmsg: signature revoked in SigRL. This means that the signature of sigrevokedmember0 is revoked in the signature based revocation list. The verification fails because the signature was generated by sigrevokedmember0, which is revoked and is an entry in the signature based revocation list of groupa (sigrl.bin).