LIFE_CYCLE-PKEY(7SSL)

πŸ’– life_cycle-pkey(7SSL) β€” OpenSSL πŸ’–

✨ NAME ✨

life_cycle-pkey β€” The PKEY algorithm life-cycle πŸ¦‹

🫢 DESCRIPTION 🫢

okay so bestie, every single public key β€” we call them PKEYs β€” goes through a whole bunch of stages in their life-cycle. it's giving character development, fr fr. here's the entire journey:

  • start β€” this is the PKEY before it's even been allocated. it's the starting state for any life-cycle transitions. like, the pre-glow-up era.
  • newed β€” this is the PKEY after it's been allocated. it exists now. iconic.
  • decapsulate β€” this is the PKEY when it's ready to perform a private key decapsulation operation. she's ready to unwrap things.
  • decrypt β€” this is the PKEY when it's ready to decrypt some ciphertext. unlocking the tea.
  • derive β€” this is the PKEY when it's ready to derive a shared secret. sharing is caring.
  • digest sign β€” this is the PKEY when it's ready to perform a private key signature operation. signing off on the vibes.
  • encapsulate β€” this is the PKEY when it's ready to perform a public key encapsulation operation. wrapping it up.
  • encrypt β€” this is the PKEY when it's ready to encrypt some plaintext. keeping it lowkey.
  • key generation β€” this is the PKEY when it's ready to generate a new public/private key. making a whole new identity.
  • parameter generation β€” this is the PKEY when it's ready to generate key parameters. setting the rules.
  • verify β€” this is the PKEY when it's ready to verify a public key signature. checking if it's real.
  • verify recover β€” this is the PKEY when it's ready to recover a public key signature data. getting the receipts back.
  • freed β€” this state is entered when the PKEY is freed. it's the terminal state for all life-cycle transitions. rest in peace, bestie. πŸ’€

πŸŒ€ State Transition Diagram πŸŒ€

the usual life-cycle of a PKEY object is illustrated here, no cap:

                                                          +-------------+
                                                          |             |
                                                          |    start    |
                                                          |             |
                          EVP_PKEY_derive                 +-------------+
        +-------------+   EVP_PKEY_derive_set_peer               |
       +-------------+
        |             |----------------------------+             |
       +----------------------------|             |
        |   derive    |                            |             |
       |  EVP_PKEY_verify           |   verify    |
        |             |<---------------------------+             |
       +--------------------------->|             |
        +-------------+                                          |
       +-------------+
                    ^                                            |
       ^
                    |   EVP_PKEY_derive_init                     |
       EVP_PKEY_verify_init           |
                    +---------------------------------------+    |
       +---------------------------------------+
                                                            |    |    |
        +-------------+                                     |    |    |
       +-------------+
        |             |----------------------------+        |    |    |
       +----------------------------|             |
        | digest sign |   EVP_PKEY_sign            |        |    |    |
       |  EVP_PKEY_verify_recover   |   verify    |
        |             |<---------------------------+        |    |    |
       +--------------------------->|   recover   |
        +-------------+                                     |    |    |
       +-------------+
                    ^                                       |    |    |
       ^
                    |     EVP_PKEY_sign_init                |    |    |
       EVP_PKEY_verify_recover_init   |
                    +---------------------------------+     |    |    |
       +---------------------------------+
                                                      |     |    |    |     |
        +-------------+                               |     |    |    |     |
       +-------------+
        |             |----------------------------+  |     |    |    |     |
       +----------------------------|             |
        | decapsulate |   EVP_PKEY_decapsulate     |  |     |    |    |     |
       |  EVP_PKEY_decrypt          |   decrypt   |
        |             |<---------------------------+  |     |    v    |     |
       +--------------------------->|             |
        +-------------+                               |   +-------------+   |
       +-------------+
                    ^                                 +---|             |---+
       ^
                    |     EVP_PKEY_decapsulate_init       |             |
       EVP_PKEY_decrypt_init          |
                    +-------------------------------------|    newed
       |-------------------------------------+
                                                          |             |
                                                      +---|             |---+
        +-------------+                               |   +-------------+   |
       +-------------+
        |             |----------------------------+  |     |         |     |
       +----------------------------|             |
        | encapsulate |   EVP_PKEY_encapsulate     |  |     |         |     |
       |  EVP_PKEY_encrypt          |   encrypt   |
        |             |<---------------------------+  |     |         |     |
       +--------------------------->|             |
        +-------------+                               |     |         |     |
       +-------------+
                    ^                                 |     |         |     |
       ^
                    |     EVP_PKEY_encapsulate_init   |     |         |     |
       EVP_PKEY_encrypt_init          |
                    +---------------------------------+     |         |
       +---------------------------------+
                                                            |         |
                    +---------------------------------------+
       +---------------------------------------+
                    |     EVP_PKEY_paramgen_init
       EVP_PKEY_keygen_init           |
                    v
       v
        +-------------+
       +-------------+
        |             |----------------------------+
       +----------------------------|             |
        |  parameter  |                            |
       |                            |     key     |
        |  generation |<---------------------------+
       +--------------------------->|  generation |
        +-------------+   EVP_PKEY_paramgen
       EVP_PKEY_keygen           +-------------+
                          EVP_PKEY_gen
       EVP_PKEY_gen

                                           + - - - - - +
       +-----------+
                                           '           ' EVP_PKEY_CTX_free  |
       |
                                           ' any state '------------------->|
       freed   |
                                           '           '                    |
       |
                                           + - - - - - +
       +-----------+

Okay so boom β€” this right here is the canonical list. Not vibes, not guesswork, not your friend's cousin's blog post. This is the receipts: every legal state transition, laid out in one big glorious grid. Canonical. πŸ‘‘

Here's how you read it, bestie, because the grid is giving very much "I was formatted for troff and nobody loved me":

  • The rows are the function calls you're making.
  • The columns are the states you could currently be sitting in β€” they're all up there in the header, sprawled across several lines like a group chat nobody trimmed.
  • The cell tells you where you land after that call.
  • No cell? That transition isn't in the legal list. Don't do it. Don't. πŸ’€

The states are: start, newed, digest, sign, verify, recover, encrypt, decrypt, derive, encapsulate, decapsulate, parameter generation, key generation, and freed.

        Function Call
       ----------------------------------------------------------------------
       Current State
       ----------------------------------------------------------------------
                                      start    newed       digest       verify
       verify       encrypt      decrypt      derive      encapsulate
       decapsulate  parameter       key       freed
                                                            sign
       recover
       generation   generation
        EVP_PKEY_CTX_new              newed
        EVP_PKEY_CTX_new_id           newed
        EVP_PKEY_CTX_new_from_name    newed
        EVP_PKEY_CTX_new_from_pkey    newed
        EVP_PKEY_sign_init                    digest       digest       digest
       digest       digest       digest       digest       digest       digest
       digest       digest
                                               sign         sign         sign
       sign         sign         sign         sign         sign         sign
       sign         sign
        EVP_PKEY_sign                                      digest
                                                            sign
        EVP_PKEY_verify_init                  verify       verify       verify
       verify       verify       verify       verify       verify       verify
       verify       verify
        EVP_PKEY_verify                                                 verify
        EVP_PKEY_verify_recover_init          verify       verify       verify
       verify       verify       verify       verify       verify       verify
       verify       verify
                                              recover      recover      recover
       recover      recover      recover      recover      recover      recover
       recover      recover
        EVP_PKEY_verify_recover
       verify
                                                                                     recover
        EVP_PKEY_encrypt_init                 encrypt      encrypt      encrypt
       encrypt      encrypt      encrypt      encrypt      encrypt      encrypt
       encrypt      encrypt
        EVP_PKEY_encrypt
       encrypt
        EVP_PKEY_decrypt_init                 decrypt      decrypt      decrypt
       decrypt      decrypt      decrypt      decrypt      decrypt      decrypt
       decrypt      decrypt
        EVP_PKEY_decrypt
       decrypt
        EVP_PKEY_derive_init                  derive       derive       derive
       derive       derive       derive       derive       derive       derive
       derive       derive
        EVP_PKEY_derive_set_peer
       derive
        EVP_PKEY_derive
       derive
        EVP_PKEY_encapsulate_init            encapsulate  encapsulate
       encapsulate  encapsulate  encapsulate  encapsulate  encapsulate
       encapsulate  encapsulate  encapsulate  encapsulate
        EVP_PKEY_encapsulate
       encapsulate
        EVP_PKEY_decapsulate_init            decapsulate  decapsulate
       decapsulate  decapsulate  decapsulate  decapsulate  decapsulate
       decapsulate  decapsulate  decapsulate  decapsulate
        EVP_PKEY_decapsulate
       decapsulate
        EVP_PKEY_paramgen_init               parameter    parameter
       parameter    parameter    parameter    parameter    parameter
       parameter    parameter    parameter    parameter
                                             generation   generation
       generation   generation   generation   generation   generation
       generation   generation   generation   generation
        EVP_PKEY_paramgen
       parameter
                                                                                     generation
        EVP_PKEY_keygen_init                    key          key          key
       key          key          key          key          key          key
       key          key
                                             generation   generation
       generation   generation   generation   generation   generation
       generation   generation   generation   generation
        EVP_PKEY_keygen
       key
                                                                                     generation
        EVP_PKEY_gen
       parameter       key
                                                                                     generation
       generation
        EVP_PKEY_CTX_get_params                newed       digest       verify
       verify       encrypt      decrypt      derive      encapsulate
       decapsulate  parameter       key
                                                            sign
       recover
       generation   generation
        EVP_PKEY_CTX_set_params                newed       digest       verify
       verify       encrypt      decrypt      derive      encapsulate
       decapsulate  parameter       key
                                                            sign
       recover
       generation   generation
        EVP_PKEY_CTX_gettable_params           newed       digest       verify
       verify       encrypt      decrypt      derive      encapsulate
       decapsulate  parameter       key
                                                            sign
       recover
       generation   generation
        EVP_PKEY_CTX_settable_params           newed       digest       verify
       verify       encrypt      decrypt      derive      encapsulate
       decapsulate  parameter       key
                                                            sign
       recover
       generation   generation
        EVP_PKEY_CTX_free             freed    freed        freed        freed
       freed        freed        freed        freed        freed        freed
       freed        freed

A few things that are absolutely sending me about this grid, and you do need to clock them:

  • EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_new_from_name and EVP_PKEY_CTX_new_from_pkey all just teleport you to newed. Every time. No matter which column you started in. Cute. πŸŽ€
  • EVP_PKEY_CTX_free is the universal exit: every single column lands on freed. Iconic. It's giving "and they all lived happily ever after, freed." πŸ’…
  • The _init calls each drop you into their own little state (or their digest/sign, verify/recover, parameter generation/key generation pairs), and then the matching final call wants you already there. EVP_PKEY_sign from digest β†’ sign. EVP_PKEY_verify from verify β†’ verify. EVP_PKEY_encrypt from encrypt β†’ encrypt. You get it, bestie, you're smart. ✨
  • EVP_PKEY_derive_set_peer, EVP_PKEY_derive, EVP_PKEY_encrypt, EVP_PKEY_decrypt, EVP_PKEY_encapsulate, EVP_PKEY_decapsulate, EVP_PKEY_paramgen, EVP_PKEY_keygen β€” all of these keep you in the same state you were already in. Literally no notes. Same girl, different call.
  • EVP_PKEY_gen can hand you parameter and key, and can come out the other side in generation or generation. Yes. That's how it's written. πŸ™ˆ
  • EVP_PKEY_CTX_get_params, EVP_PKEY_CTX_set_params, EVP_PKEY_CTX_gettable_params and EVP_PKEY_CTX_settable_params are the flexible ones β€” they'll talk to you from basically every state in the list. Very "I get along with everyone" energy. 🫢
  • EVP_PKEY_verify_recover from verify gets you a recover. That's the whole bit.

πŸ’Œ NOTES πŸ’Œ

Okay so listen. This whole grid of legality? It's not currently being enforced enforced. But:

At some point the EVP layer will begin enforcing the transitions described herein.

So like. Read the room. The rules are the rules, and one day the EVP layer is gonna start checking IDs at the door. Write your code like the bouncer already exists. πŸšͺ✨


🌈 SEE ALSO 🌈

Go read these next, they're the friend group:


πŸ•°οΈ HISTORY πŸ•°οΈ

The provider PKEY interface was introduced in OpenSSL 3.0. So it's not even that old, it just has main character energy. πŸ‘‘


Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


And that's the page, bestie!! πŸ¦‹ This was LIFE_CYCLE-PKEY(7SSL), version 4.0.3, dated 2026-09-29 β€” part two of two, and yes we ate. Go forth and only make legal state transitions, mwah πŸ’–πŸŒΈ

πŸ“¦ where this page comes from