cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amd-memory-encryption.rst (18699B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3======================================
      4Secure Encrypted Virtualization (SEV)
      5======================================
      6
      7Overview
      8========
      9
     10Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
     11
     12SEV is an extension to the AMD-V architecture which supports running
     13virtual machines (VMs) under the control of a hypervisor. When enabled,
     14the memory contents of a VM will be transparently encrypted with a key
     15unique to that VM.
     16
     17The hypervisor can determine the SEV support through the CPUID
     18instruction. The CPUID function 0x8000001f reports information related
     19to SEV::
     20
     21	0x8000001f[eax]:
     22			Bit[1] 	indicates support for SEV
     23	    ...
     24		  [ecx]:
     25			Bits[31:0]  Number of encrypted guests supported simultaneously
     26
     27If support for SEV is present, MSR 0xc001_0010 (MSR_AMD64_SYSCFG) and MSR 0xc001_0015
     28(MSR_K7_HWCR) can be used to determine if it can be enabled::
     29
     30	0xc001_0010:
     31		Bit[23]	   1 = memory encryption can be enabled
     32			   0 = memory encryption can not be enabled
     33
     34	0xc001_0015:
     35		Bit[0]	   1 = memory encryption can be enabled
     36			   0 = memory encryption can not be enabled
     37
     38When SEV support is available, it can be enabled in a specific VM by
     39setting the SEV bit before executing VMRUN.::
     40
     41	VMCB[0x90]:
     42		Bit[1]	    1 = SEV is enabled
     43			    0 = SEV is disabled
     44
     45SEV hardware uses ASIDs to associate a memory encryption key with a VM.
     46Hence, the ASID for the SEV-enabled guests must be from 1 to a maximum value
     47defined in the CPUID 0x8000001f[ecx] field.
     48
     49SEV Key Management
     50==================
     51
     52The SEV guest key management is handled by a separate processor called the AMD
     53Secure Processor (AMD-SP). Firmware running inside the AMD-SP provides a secure
     54key management interface to perform common hypervisor activities such as
     55encrypting bootstrap code, snapshot, migrating and debugging the guest. For more
     56information, see the SEV Key Management spec [api-spec]_
     57
     58The main ioctl to access SEV is KVM_MEMORY_ENCRYPT_OP.  If the argument
     59to KVM_MEMORY_ENCRYPT_OP is NULL, the ioctl returns 0 if SEV is enabled
     60and ``ENOTTY` if it is disabled (on some older versions of Linux,
     61the ioctl runs normally even with a NULL argument, and therefore will
     62likely return ``EFAULT``).  If non-NULL, the argument to KVM_MEMORY_ENCRYPT_OP
     63must be a struct kvm_sev_cmd::
     64
     65       struct kvm_sev_cmd {
     66               __u32 id;
     67               __u64 data;
     68               __u32 error;
     69               __u32 sev_fd;
     70       };
     71
     72
     73The ``id`` field contains the subcommand, and the ``data`` field points to
     74another struct containing arguments specific to command.  The ``sev_fd``
     75should point to a file descriptor that is opened on the ``/dev/sev``
     76device, if needed (see individual commands).
     77
     78On output, ``error`` is zero on success, or an error code.  Error codes
     79are defined in ``<linux/psp-dev.h>``.
     80
     81KVM implements the following commands to support common lifecycle events of SEV
     82guests, such as launching, running, snapshotting, migrating and decommissioning.
     83
     841. KVM_SEV_INIT
     85---------------
     86
     87The KVM_SEV_INIT command is used by the hypervisor to initialize the SEV platform
     88context. In a typical workflow, this command should be the first command issued.
     89
     90The firmware can be initialized either by using its own non-volatile storage or
     91the OS can manage the NV storage for the firmware using the module parameter
     92``init_ex_path``. The file specified by ``init_ex_path`` must exist. To create
     93a new NV storage file allocate the file with 32KB bytes of 0xFF as required by
     94the SEV spec.
     95
     96Returns: 0 on success, -negative on error
     97
     982. KVM_SEV_LAUNCH_START
     99-----------------------
    100
    101The KVM_SEV_LAUNCH_START command is used for creating the memory encryption
    102context. To create the encryption context, user must provide a guest policy,
    103the owner's public Diffie-Hellman (PDH) key and session information.
    104
    105Parameters: struct  kvm_sev_launch_start (in/out)
    106
    107Returns: 0 on success, -negative on error
    108
    109::
    110
    111        struct kvm_sev_launch_start {
    112                __u32 handle;           /* if zero then firmware creates a new handle */
    113                __u32 policy;           /* guest's policy */
    114
    115                __u64 dh_uaddr;         /* userspace address pointing to the guest owner's PDH key */
    116                __u32 dh_len;
    117
    118                __u64 session_addr;     /* userspace address which points to the guest session information */
    119                __u32 session_len;
    120        };
    121
    122On success, the 'handle' field contains a new handle and on error, a negative value.
    123
    124KVM_SEV_LAUNCH_START requires the ``sev_fd`` field to be valid.
    125
    126For more details, see SEV spec Section 6.2.
    127
    1283. KVM_SEV_LAUNCH_UPDATE_DATA
    129-----------------------------
    130
    131The KVM_SEV_LAUNCH_UPDATE_DATA is used for encrypting a memory region. It also
    132calculates a measurement of the memory contents. The measurement is a signature
    133of the memory contents that can be sent to the guest owner as an attestation
    134that the memory was encrypted correctly by the firmware.
    135
    136Parameters (in): struct  kvm_sev_launch_update_data
    137
    138Returns: 0 on success, -negative on error
    139
    140::
    141
    142        struct kvm_sev_launch_update {
    143                __u64 uaddr;    /* userspace address to be encrypted (must be 16-byte aligned) */
    144                __u32 len;      /* length of the data to be encrypted (must be 16-byte aligned) */
    145        };
    146
    147For more details, see SEV spec Section 6.3.
    148
    1494. KVM_SEV_LAUNCH_MEASURE
    150-------------------------
    151
    152The KVM_SEV_LAUNCH_MEASURE command is used to retrieve the measurement of the
    153data encrypted by the KVM_SEV_LAUNCH_UPDATE_DATA command. The guest owner may
    154wait to provide the guest with confidential information until it can verify the
    155measurement. Since the guest owner knows the initial contents of the guest at
    156boot, the measurement can be verified by comparing it to what the guest owner
    157expects.
    158
    159If len is zero on entry, the measurement blob length is written to len and
    160uaddr is unused.
    161
    162Parameters (in): struct  kvm_sev_launch_measure
    163
    164Returns: 0 on success, -negative on error
    165
    166::
    167
    168        struct kvm_sev_launch_measure {
    169                __u64 uaddr;    /* where to copy the measurement */
    170                __u32 len;      /* length of measurement blob */
    171        };
    172
    173For more details on the measurement verification flow, see SEV spec Section 6.4.
    174
    1755. KVM_SEV_LAUNCH_FINISH
    176------------------------
    177
    178After completion of the launch flow, the KVM_SEV_LAUNCH_FINISH command can be
    179issued to make the guest ready for the execution.
    180
    181Returns: 0 on success, -negative on error
    182
    1836. KVM_SEV_GUEST_STATUS
    184-----------------------
    185
    186The KVM_SEV_GUEST_STATUS command is used to retrieve status information about a
    187SEV-enabled guest.
    188
    189Parameters (out): struct kvm_sev_guest_status
    190
    191Returns: 0 on success, -negative on error
    192
    193::
    194
    195        struct kvm_sev_guest_status {
    196                __u32 handle;   /* guest handle */
    197                __u32 policy;   /* guest policy */
    198                __u8 state;     /* guest state (see enum below) */
    199        };
    200
    201SEV guest state:
    202
    203::
    204
    205        enum {
    206        SEV_STATE_INVALID = 0;
    207        SEV_STATE_LAUNCHING,    /* guest is currently being launched */
    208        SEV_STATE_SECRET,       /* guest is being launched and ready to accept the ciphertext data */
    209        SEV_STATE_RUNNING,      /* guest is fully launched and running */
    210        SEV_STATE_RECEIVING,    /* guest is being migrated in from another SEV machine */
    211        SEV_STATE_SENDING       /* guest is getting migrated out to another SEV machine */
    212        };
    213
    2147. KVM_SEV_DBG_DECRYPT
    215----------------------
    216
    217The KVM_SEV_DEBUG_DECRYPT command can be used by the hypervisor to request the
    218firmware to decrypt the data at the given memory region.
    219
    220Parameters (in): struct kvm_sev_dbg
    221
    222Returns: 0 on success, -negative on error
    223
    224::
    225
    226        struct kvm_sev_dbg {
    227                __u64 src_uaddr;        /* userspace address of data to decrypt */
    228                __u64 dst_uaddr;        /* userspace address of destination */
    229                __u32 len;              /* length of memory region to decrypt */
    230        };
    231
    232The command returns an error if the guest policy does not allow debugging.
    233
    2348. KVM_SEV_DBG_ENCRYPT
    235----------------------
    236
    237The KVM_SEV_DEBUG_ENCRYPT command can be used by the hypervisor to request the
    238firmware to encrypt the data at the given memory region.
    239
    240Parameters (in): struct kvm_sev_dbg
    241
    242Returns: 0 on success, -negative on error
    243
    244::
    245
    246        struct kvm_sev_dbg {
    247                __u64 src_uaddr;        /* userspace address of data to encrypt */
    248                __u64 dst_uaddr;        /* userspace address of destination */
    249                __u32 len;              /* length of memory region to encrypt */
    250        };
    251
    252The command returns an error if the guest policy does not allow debugging.
    253
    2549. KVM_SEV_LAUNCH_SECRET
    255------------------------
    256
    257The KVM_SEV_LAUNCH_SECRET command can be used by the hypervisor to inject secret
    258data after the measurement has been validated by the guest owner.
    259
    260Parameters (in): struct kvm_sev_launch_secret
    261
    262Returns: 0 on success, -negative on error
    263
    264::
    265
    266        struct kvm_sev_launch_secret {
    267                __u64 hdr_uaddr;        /* userspace address containing the packet header */
    268                __u32 hdr_len;
    269
    270                __u64 guest_uaddr;      /* the guest memory region where the secret should be injected */
    271                __u32 guest_len;
    272
    273                __u64 trans_uaddr;      /* the hypervisor memory region which contains the secret */
    274                __u32 trans_len;
    275        };
    276
    27710. KVM_SEV_GET_ATTESTATION_REPORT
    278----------------------------------
    279
    280The KVM_SEV_GET_ATTESTATION_REPORT command can be used by the hypervisor to query the attestation
    281report containing the SHA-256 digest of the guest memory and VMSA passed through the KVM_SEV_LAUNCH
    282commands and signed with the PEK. The digest returned by the command should match the digest
    283used by the guest owner with the KVM_SEV_LAUNCH_MEASURE.
    284
    285If len is zero on entry, the measurement blob length is written to len and
    286uaddr is unused.
    287
    288Parameters (in): struct kvm_sev_attestation
    289
    290Returns: 0 on success, -negative on error
    291
    292::
    293
    294        struct kvm_sev_attestation_report {
    295                __u8 mnonce[16];        /* A random mnonce that will be placed in the report */
    296
    297                __u64 uaddr;            /* userspace address where the report should be copied */
    298                __u32 len;
    299        };
    300
    30111. KVM_SEV_SEND_START
    302----------------------
    303
    304The KVM_SEV_SEND_START command can be used by the hypervisor to create an
    305outgoing guest encryption context.
    306
    307If session_len is zero on entry, the length of the guest session information is
    308written to session_len and all other fields are not used.
    309
    310Parameters (in): struct kvm_sev_send_start
    311
    312Returns: 0 on success, -negative on error
    313
    314::
    315
    316        struct kvm_sev_send_start {
    317                __u32 policy;                 /* guest policy */
    318
    319                __u64 pdh_cert_uaddr;         /* platform Diffie-Hellman certificate */
    320                __u32 pdh_cert_len;
    321
    322                __u64 plat_certs_uaddr;        /* platform certificate chain */
    323                __u32 plat_certs_len;
    324
    325                __u64 amd_certs_uaddr;        /* AMD certificate */
    326                __u32 amd_certs_len;
    327
    328                __u64 session_uaddr;          /* Guest session information */
    329                __u32 session_len;
    330        };
    331
    33212. KVM_SEV_SEND_UPDATE_DATA
    333----------------------------
    334
    335The KVM_SEV_SEND_UPDATE_DATA command can be used by the hypervisor to encrypt the
    336outgoing guest memory region with the encryption context creating using
    337KVM_SEV_SEND_START.
    338
    339If hdr_len or trans_len are zero on entry, the length of the packet header and
    340transport region are written to hdr_len and trans_len respectively, and all
    341other fields are not used.
    342
    343Parameters (in): struct kvm_sev_send_update_data
    344
    345Returns: 0 on success, -negative on error
    346
    347::
    348
    349        struct kvm_sev_launch_send_update_data {
    350                __u64 hdr_uaddr;        /* userspace address containing the packet header */
    351                __u32 hdr_len;
    352
    353                __u64 guest_uaddr;      /* the source memory region to be encrypted */
    354                __u32 guest_len;
    355
    356                __u64 trans_uaddr;      /* the destination memory region  */
    357                __u32 trans_len;
    358        };
    359
    36013. KVM_SEV_SEND_FINISH
    361------------------------
    362
    363After completion of the migration flow, the KVM_SEV_SEND_FINISH command can be
    364issued by the hypervisor to delete the encryption context.
    365
    366Returns: 0 on success, -negative on error
    367
    36814. KVM_SEV_SEND_CANCEL
    369------------------------
    370
    371After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the
    372SEND_CANCEL command to stop a migration. This is necessary so that a cancelled
    373migration can restart with a new target later.
    374
    375Returns: 0 on success, -negative on error
    376
    37715. KVM_SEV_RECEIVE_START
    378-------------------------
    379
    380The KVM_SEV_RECEIVE_START command is used for creating the memory encryption
    381context for an incoming SEV guest. To create the encryption context, the user must
    382provide a guest policy, the platform public Diffie-Hellman (PDH) key and session
    383information.
    384
    385Parameters: struct  kvm_sev_receive_start (in/out)
    386
    387Returns: 0 on success, -negative on error
    388
    389::
    390
    391        struct kvm_sev_receive_start {
    392                __u32 handle;           /* if zero then firmware creates a new handle */
    393                __u32 policy;           /* guest's policy */
    394
    395                __u64 pdh_uaddr;        /* userspace address pointing to the PDH key */
    396                __u32 pdh_len;
    397
    398                __u64 session_uaddr;    /* userspace address which points to the guest session information */
    399                __u32 session_len;
    400        };
    401
    402On success, the 'handle' field contains a new handle and on error, a negative value.
    403
    404For more details, see SEV spec Section 6.12.
    405
    40616. KVM_SEV_RECEIVE_UPDATE_DATA
    407-------------------------------
    408
    409The KVM_SEV_RECEIVE_UPDATE_DATA command can be used by the hypervisor to copy
    410the incoming buffers into the guest memory region with encryption context
    411created during the KVM_SEV_RECEIVE_START.
    412
    413Parameters (in): struct kvm_sev_receive_update_data
    414
    415Returns: 0 on success, -negative on error
    416
    417::
    418
    419        struct kvm_sev_launch_receive_update_data {
    420                __u64 hdr_uaddr;        /* userspace address containing the packet header */
    421                __u32 hdr_len;
    422
    423                __u64 guest_uaddr;      /* the destination guest memory region */
    424                __u32 guest_len;
    425
    426                __u64 trans_uaddr;      /* the incoming buffer memory region  */
    427                __u32 trans_len;
    428        };
    429
    43017. KVM_SEV_RECEIVE_FINISH
    431--------------------------
    432
    433After completion of the migration flow, the KVM_SEV_RECEIVE_FINISH command can be
    434issued by the hypervisor to make the guest ready for execution.
    435
    436Returns: 0 on success, -negative on error
    437
    43818. KVM_SNP_INIT
    439----------------
    440
    441The KVM_SNP_INIT command can be used by the hypervisor to initialize SEV-SNP
    442context. In a typical workflow, this command should be the first command issued.
    443
    444Parameters (in/out): struct kvm_snp_init
    445
    446Returns: 0 on success, -negative on error
    447
    448::
    449
    450        struct kvm_snp_init {
    451                __u64 flags;
    452        };
    453
    454The flags bitmap is defined as::
    455
    456   /* enable the restricted injection */
    457   #define KVM_SEV_SNP_RESTRICTED_INJET   (1<<0)
    458
    459   /* enable the restricted injection timer */
    460   #define KVM_SEV_SNP_RESTRICTED_TIMER_INJET   (1<<1)
    461
    462If the specified flags is not supported then return -EOPNOTSUPP, and the supported
    463flags are returned.
    464
    46519. KVM_SNP_LAUNCH_START
    466------------------------
    467
    468The KVM_SNP_LAUNCH_START command is used for creating the memory encryption
    469context for the SEV-SNP guest. To create the encryption context, user must
    470provide a guest policy, migration agent (if any) and guest OS visible
    471workarounds value as defined SEV-SNP specification.
    472
    473Parameters (in): struct  kvm_snp_launch_start
    474
    475Returns: 0 on success, -negative on error
    476
    477::
    478
    479        struct kvm_sev_snp_launch_start {
    480                __u64 policy;           /* Guest policy to use. */
    481                __u64 ma_uaddr;         /* userspace address of migration agent */
    482                __u8 ma_en;             /* 1 if the migtation agent is enabled */
    483                __u8 imi_en;            /* set IMI to 1. */
    484                __u8 gosvw[16];         /* guest OS visible workarounds */
    485        };
    486
    487See the SEV-SNP specification for further detail on the launch input.
    488
    48920. KVM_SNP_LAUNCH_UPDATE
    490-------------------------
    491
    492The KVM_SNP_LAUNCH_UPDATE is used for encrypting a memory region. It also
    493calculates a measurement of the memory contents. The measurement is a signature
    494of the memory contents that can be sent to the guest owner as an attestation
    495that the memory was encrypted correctly by the firmware.
    496
    497Parameters (in): struct  kvm_snp_launch_update
    498
    499Returns: 0 on success, -negative on error
    500
    501::
    502
    503        struct kvm_sev_snp_launch_update {
    504                __u64 start_gfn;        /* Guest page number to start from. */
    505                __u64 uaddr;            /* userspace address need to be encrypted */
    506                __u32 len;              /* length of memory region */
    507                __u8 imi_page;          /* 1 if memory is part of the IMI */
    508                __u8 page_type;         /* page type */
    509                __u8 vmpl3_perms;       /* VMPL3 permission mask */
    510                __u8 vmpl2_perms;       /* VMPL2 permission mask */
    511                __u8 vmpl1_perms;       /* VMPL1 permission mask */
    512        };
    513
    514See the SEV-SNP spec for further details on how to build the VMPL permission
    515mask and page type.
    516
    51721. KVM_SNP_LAUNCH_FINISH
    518-------------------------
    519
    520After completion of the SNP guest launch flow, the KVM_SNP_LAUNCH_FINISH command can be
    521issued to make the guest ready for the execution.
    522
    523Parameters (in): struct kvm_sev_snp_launch_finish
    524
    525Returns: 0 on success, -negative on error
    526
    527::
    528
    529        struct kvm_sev_snp_launch_finish {
    530                __u64 id_block_uaddr;
    531                __u64 id_auth_uaddr;
    532                __u8 id_block_en;
    533                __u8 auth_key_en;
    534                __u8 host_data[32];
    535        };
    536
    537
    538See SEV-SNP specification for further details on launch finish input parameters.
    539
    540References
    541==========
    542
    543
    544See [white-paper]_, [api-spec]_, [amd-apm]_ and [kvm-forum]_ for more info.
    545
    546.. [white-paper] http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
    547.. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf
    548.. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34)
    549.. [kvm-forum]  https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf