Skip to main content

Generate local (insecure) root key and certificate

The version 3 (v3 and v3_attest) extensions define the certificate format and establish the Certificate Authority (CA). This process allows you to create a local CA with specific attributes and constraints set by the v3 extensions, allowing you to issue certificates for testing and development purposes. Follow these steps to generate a local root key and certificate.
  1. Create an opensslroot.cfg using the following sample OpenSSL configuration file: OpenSSL is an open-source toolkit for secure sockets layer (SSL) and transport layer security (TLS) protocols, offering cryptographic functions and a command-line tool. The following sample OpenSSL configuration file is used for generating certificate requests and managing a Certificate Authority (CA).
    #
    #  Copyright (c) 2013 Qualcomm Technologies, Inc.
    #  All Rights Reserved.
    #  Confidential and Proprietary - Qualcomm Technologies, Inc.
    #
    # OpenSSL example configuration file.
    # This is mostly being used for generation of certificate requests.
    #
    
    # This definition stops the following lines choking if HOME isn't
    # defined.
    HOME            = .
    RANDFILE        = $ENV::HOME/.rnd
    
    # Extra OBJECT IDENTIFIER info:
    #oid_file       = $ENV::HOME/.oid
    oid_section     = new_oids
    
    # To use this configuration file with the "-extfile" option of the
    # "openssl x509" utility, name here the section containing the
    # X.509v3 extensions to use:
    # extensions        =
    # (Alternatively, use a configuration file that has only
    # X.509v3 extensions in its main [= default] section.)
    
    [ new_oids ]
    
    # We can add new OIDs in here for use by 'ca' and 'req'.
    # Add a simple OID like this:
    # testoid1=1.2.3.4
    # Or use config file substitution like this:
    # testoid2=${testoid1}.5.6
    
    ####################################################################
    [ ca ]
    default_ca  = CA_default        # The default ca section
    
    ####################################################################
    [ CA_default ]
    
    dir     = ./demoCA      # Where everything is kept
    certs       = $dir/certs        # Where the issued certs are kept
    crl_dir     = $dir/crl      # Where the issued crl are kept
    database    = $dir/index.txt    # database index file.
    #unique_subject = no            # Set to 'no' to allow creation of
    # several certificates with same subject.
    new_certs_dir   = $dir/newcerts     # default place for new certs.
    
    certificate = $dir/cacert.pem   # The CA certificate
    serial      = $dir/serial       # The current serial number
    crlnumber   = $dir/crlnumber    # the current crl number
    # must be commented out to leave a V1 CRL
    crl     = $dir/crl.pem      # The current CRL
    private_key = $dir/private/cakey.pem# The private key
    RANDFILE    = $dir/private/.rand    # private random number file
    
    x509_extensions = usr_cert      # The extensions to add to the cert
    
    # Comment out the following two lines for the "traditional"
    # (and highly broken) format.
    name_opt    = ca_default        # Subject Name options
    cert_opt    = ca_default        # Certificate field options
    
    # Extension copying option: use with caution.
    # copy_extensions = copy
    
    # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
    # so this is commented out by default to leave a V1 CRL.
    # crlnumber must also be commented out to leave a V1 CRL.
    # crl_extensions    = crl_ext
    
    default_days    = 365           # how long to certify for
    default_crl_days= 30            # how long before next CRL
    default_md  = sha1          # which md to use.
    preserve    = no            # keep passed DN ordering
    
    # A few different ways of specifying how similar the request should look
    # For type CA, the listed attributes must be the same, and the optional
    # and supplied fields are just that :-)
    policy      = policy_match
    
    # For the CA policy
    [ policy_match ]
    countryName     = match
    stateOrProvinceName = match
    organizationName    = match
    organizationalUnitName  = optional
    commonName      = supplied
    emailAddress        = optional
    
    # For the 'anything' policy
    # At this point in time, you must list all acceptable 'object'
    # types.
    [ policy_anything ]
    countryName     = optional
    stateOrProvinceName = optional
    localityName        = optional
    organizationName    = optional
    organizationalUnitName  = optional
    commonName      = supplied
    emailAddress        = optional
    
    ####################################################################
    [ req ]
    default_bits        = 1024
    default_keyfile     = privkey.pem
    distinguished_name  = req_distinguished_name
    attributes      = req_attributes
    x509_extensions = v3_ca # The extensions to add to the self signed cert
    
    # Passwords for private keys if not present they will be prompted for
    # input_password = secret
    # output_password = secret
    
    # This sets a mask for permitted string types. There are several options.
    # default: PrintableString, T61String, BMPString.
    # pkix   : PrintableString, BMPString.
    # utf8only: only UTF8Strings.
    # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
    # MASK:XXXX a literal mask value.
    # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
    # so use this option with caution!
    string_mask = nombstr
    
    req_extensions = v3_req # The extensions to add to a certificate request
    
    [ req_distinguished_name ]
    countryName         = Country Name (2 letter code)
    countryName_default     = AU
    countryName_min         = 2
    countryName_max         = 2
    
    stateOrProvinceName     = State or Province Name (full name)
    stateOrProvinceName_default = Some-State
    
    localityName            = Locality Name (eg, city)
    
    0.organizationName      = Organization Name (eg, company)
    0.organizationName_default  = Internet Widgits Pty Ltd
    
    # we can do this but it is not needed normally :-)
    #1.organizationName     = Second Organization Name (eg, company)
    #1.organizationName_default = World Wide Web Pty Ltd
    
    organizationalUnitName      = Organizational Unit Name (eg, section)
    #organizationalUnitName_default =
    
    commonName          = Common Name (eg, YOUR name)
    commonName_max          = 64
    
    emailAddress            = Email Address
    emailAddress_max        = 64
    
    # SET-ex3           = SET extension number 3
    
    [ req_attributes ]
    challengePassword       = A challenge password
    challengePassword_min       = 4
    challengePassword_max       = 20
    
    unstructuredName        = An optional company name
    
    [ usr_cert ]
    
    # These extensions are added when 'ca' signs a request.
    
    # This goes against PKIX guidelines but some CAs do it and some software
    # requires this to avoid interpreting an end user certificate as a CA.
    
    basicConstraints=CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    
    # Here are some examples of the usage of nsCertType. If it is omitted
    # the certificate can be used for anything *except* object signing.
    
    # This is OK for an SSL server.
    # nsCertType            = server
    
    # For an object signing certificate this would be used.
    # nsCertType = objsign
    
    # For normal client use this is typical
    # nsCertType = client, email
    
    # and for everything including object signing:
    # nsCertType = client, email, objsign
    
    # This is typical in keyUsage for a client certificate.
    # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    
    # This will be displayed in Netscape's comment listbox.
    nsComment           = "OpenSSL Generated Certificate"
    
    # PKIX recommendations harmless if included in all certificates.
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer
    
    # This stuff is for subjectAltName and issuerAltname.
    # Import the email address.
    # subjectAltName=email:copy
    # An alternative to produce certificates that aren't
    # deprecated according to PKIX.
    # subjectAltName=email:move
    
    # Copy subject details
    # issuerAltName=issuer:copy
    
    #nsCaRevocationUrl      = http://www.domain.dom/ca-crl.pem
    #nsBaseUrl
    #nsRevocationUrl
    #nsRenewalUrl
    #nsCaPolicyUrl
    #nsSslServerName
    
    [ v3_req ]
    
    # Extensions to add to a certificate request
    
    subjectKeyIdentifier=hash
    
    #authorityKeyIdentifier=keyid:always,issuer:always
    
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    
    [ v3_ca ]
    
    
    # Extensions for a typical CA
    
    
    # PKIX recommendation.
    
    subjectKeyIdentifier=hash
    
    #authorityKeyIdentifier=keyid:always,issuer:always
    
    # This is what PKIX recommends but some broken software chokes on critical
    # extensions.
    #basicConstraints = critical,CA:true
    # So we do this instead.
    basicConstraints = CA:true
    
    # Key usage: this is typical for a CA certificate. However since it will
    # prevent it from being used as a test self-signed certificate, it is best to be
    # left out as a default.
    keyUsage = cRLSign, keyCertSign
    
    # Some might want this also
    # nsCertType = sslCA, emailCA
    
    # Include email address in subject alt name: another PKIX recommendation
    # subjectAltName=email:copy
    # Copy issuer details
    # issuerAltName=issuer:copy
    
    # DER hex encoding of an extension: beware experts only!
    # obj=DER:02:03
    # Where 'obj' is a standard or added object
    # You can even override a supported extension:
    # basicConstraints= critical, DER:30:03:01:01:FF
    
    [ crl_ext ]
    
    # CRL extensions.
    # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
    
    # issuerAltName=issuer:copy
    authorityKeyIdentifier=keyid:always,issuer:always
    
    [ proxy_cert_ext ]
    # These extensions should be added when creating a proxy certificate
    
    # This goes against PKIX guidelines but some CAs do it and some software
    # requires this to avoid interpreting an end user certificate as a CA.
    
    basicConstraints=CA:FALSE
    
    # Here are some examples of the usage of nsCertType. If it is omitted
    # the certificate can be used for anything *except* object signing.
    
    # This is OK for an SSL server.
    # nsCertType            = server
    
    # For an object signing certificate this would be used.
    # nsCertType = objsign
    
    # For normal client use this is typical
    # nsCertType = client, email
    
    # and for everything including object signing:
    # nsCertType = client, email, objsign
    
    # This is typical in keyUsage for a client certificate.
    # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    
    # This will be displayed in Netscape's comment listbox.
    nsComment           = "OpenSSL Generated Certificate"
    
    # PKIX recommendations harmless if included in all certificates.
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer:always
    
    # This stuff is for subjectAltName and issuerAltname.
    # Import the email address.
    # subjectAltName=email:copy
    # An alternative to produce certificates that aren't
    # deprecated according to PKIX.
    # subjectAltName=email:move
    
    # Copy subject details
    # issuerAltName=issuer:copy
    
    #nsCaRevocationUrl      = http://www.domain.dom/ca-crl.pem
    #nsBaseUrl
    #nsRevocationUrl
    #nsRenewalUrl
    #nsCaPolicyUrl
    #nsSslServerName
    
    # This really needs to be in place for it to be a proxy certificate.
    proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
    
    Note While running any OpenSSL commands on Windows platform, if you get error such as:
    • Can’t load /home/slua_xxxx/.rnd into RNG.
      xxxx:error:xxxx:random number generator:RAND_load_file:Can’t open file:crypto/rand/randfile.c:98:Filename=/home/slua_xxxx/.rnd
    • Can’t write random bytes.
    xxxx:error:xxxx:random number generator:RAND_write_file:Can’t open file:crypto/rand/randfile.c:233:Filename=/home/slua_xxxx/.rnd
    Commment out the following line from the opensslroot.cfg file:
    RANDFILE = $ENV::HOME/.rnd
  2. To create the v3.ext and v3_attest.ext extensions, use the following:
  3. Prepare the environment, create a directory named OEM-KEYS to generate all certificates and keys at one location.
    • For Linux, use the following commands:
      cd /path/to/sectools/
      $ mkdir ./OEM-KEYS &&
      cp /download/opensslroot.cfg ./OEM-KEYS &&
      cp /download/v3.ext ./OEM-KEYS &&
      cp /download/v3_attest.ext ./OEM-KEYS
      
    • For Windows, copy opensslroot.cfg, v3.ext, and v3_attest.ext to the OEM-KEYS directory.
The table lists the supported cryptographic algorithms. Table : Cryptographic algorithms
IQ-615QCS5430/QCS6490, IQ-9075/IQ-9100, IQ-8275/IQ-8300
RSA OnlyECDSA, RSA
The table lists the supported configuration by cryptographic algorithms. Table : Configurations for cryptographic algorithms
ECDSARSA
Key Size/CurveSECP384R1 Curve2048, 4096
Signature Algorithm SupportSHA384SHA256
ExponentNA65537
Note The PK HASH used for fusing in QFPROM region is SHA-384 for all configurations, irrespective of the signature algorithm used.

Generate a key pair for secure boot

Select one of the supported algorithms to enable secure boot on the device using either ECDSA or RSA.
For support cryptographic algorithms see the Cryptographic algorithms table. Note ECDSA is recommended over RSA for better security, if supported.

Option 1: Generate ECDSA root key and certificate

ECDSA offers superior security and performance compared to the RSA signature algorithm. As a result, the default configuration in SecTools supports ECDSA signing. The following types of keys are created with ECDSA: - The public key, which is accessible to everyone. - The private key, which is only known to the owner of the key pair. You can modify and run the following ECDSA-specific commands to generate the root key and certificate:
  1. Go to the OEM-KEYS directory and generate the ECDSA root key and certificate:
    cd ./OEM-KEYS
    openssl ecparam -genkey -name secp384r1 -outform PEM -out qpsa_rootca.key
    
    openssl req -new -key qpsa_rootca.key -sha384 -out rootca_pem.crt -subj "/C=US/CN=Generated OEM Root CA/OU=CDMA Technologies/OU=General Use OEM Key (OEM should update all fields)/L=San Diego/O=SecTools/ST=California" -config opensslroot.cfg -x509 -days 7300 -set_serial 1
    
    openssl x509 -in rootca_pem.crt -inform PEM -out qpsa_rootca.cer -outform DER
    
  2. Generate the intermediate Certificate Authority (CA) key pair and certificate:
    openssl ecparam -genkey -name secp384r1 -outform PEM -out qpsa_attestca.key
    
    openssl req -new -key qpsa_attestca.key -out ca.CSR -subj "/C=US/ST=California/CN=Generated OEM Attestation CA/O=SecTools/L=San Diego" -config opensslroot.cfg -sha384
    
    openssl x509 -req -in ca.CSR -CA rootca_pem.crt -CAkey qpsa_rootca.key -out ca_pem.crt -set_serial 1 -days 7300 -extfile v3.ext -sha384 -CAcreateserial
    
    openssl x509 -inform PEM -in ca_pem.crt -outform DER -out qpsa_attestca.cer
    

Option 2: Generate RSA key pair and certificate

The RSA signature algorithm uses asymmetric keys (public/private) to verify message authenticity and integrity. A private key and a public key are created with RSA:
  • The public key is accessible to anyone.
  • The private key is only known to the owner of the key pair.
An image is signed with the RSA private key chain and verified with the OEM public key or certificate chain (Anchored in fuses). Follow these steps to generate RSA Key pair and certificates.
  1. To generate the root client application key pair and certificate, run the following commands: The key size used is 2048. However, a key size of 4096 is also supported.
    openssl genrsa -out qpsa_rootca.key 2048
    
    openssl req -new -sha256 -key qpsa_rootca.key -x509 -out rootca_pem.crt -subj /C=US/ST=California/L="San Diego"/OU="General Use Test Key (for testing 13 only)"/OU="CDMA Technologies"/O=QUALCOMM/CN="QCT Root CA 1" -days 7300 -set_serial 1 -config opensslroot.cfg -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sigopt digest:sha256
    .. note:: For OpenSSL > 3.x, don't pass the ``-sigopt digest:sha256`` option.
    
    openssl x509 -in rootca_pem.crt -inform PEM -out qpsa_rootca.cer -outform DER
    
    openssl x509 -text -inform DER -in qpsa_rootca.cer
    
  2. To generate the attestation client application key pair and certificate, run the following commands using RSA with a key size of 2048:
    openssl genrsa -out qpsa_attestca.key 2048
    
    openssl req -new -key qpsa_attestca.key -out attestca.csr -subj "/C=US/ST=California/L=San Diego/OU=CDMA Technologies/O=QUALCOMM/CN=QUALCOMM Attestation CA" -days 7300 -config opensslroot.cfg
    
    openssl x509 -req -in attestca.csr -CA rootca_pem.crt -CAkey qpsa_rootca.key -out attestca_pem.crt -set_serial 5 -days 7300 -extfile v3.ext -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
    
    Note For OpenSSL > 3.x, don’t pass the -sigopt digest:sha256 option.
    openssl x509 -inform PEM -in attestca_pem.crt -outform DER -out qpsa_attestca.cer
    

Generate SHA-384 hash for RSA and ECDSA

The SHA-384 hash is crucial in cryptographic applications for several reasons, including enhancing security strength, creating digital signatures, ensuring compliance with standards, and future-proofing. SHA-384 will be used as the RoT and ensure the authenticity and integrity of software images To generate the SHA-384 hash of the root certificate, run the following command:
openssl dgst -sha384 qpsa_rootca.cer >sha384rootcert.txt

Next steps

  • To ensure the authenticity and integrity of software images and to write a complete software image, see Sign and flash the images.
  • To ensure device security by allowing only digitally signed images to be programmed, see Perform VIP flashing.