]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Include/Protocol/BlockIoCrypto.h
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Include / Protocol / BlockIoCrypto.h
1 /** @file
2 The UEFI Inline Cryptographic Interface protocol provides services to abstract
3 access to inline cryptographic capabilities.
4
5 Copyright (c) 2015-2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 @par Revision Reference:
9 This Protocol was introduced in UEFI Specification 2.5.
10
11 **/
12
13 #ifndef __BLOCK_IO_CRYPTO_H__
14 #define __BLOCK_IO_CRYPTO_H__
15
16 #include <Protocol/BlockIo.h>
17
18 #define EFI_BLOCK_IO_CRYPTO_PROTOCOL_GUID \
19 { \
20 0xa00490ba, 0x3f1a, 0x4b4c, {0xab, 0x90, 0x4f, 0xa9, 0x97, 0x26, 0xa1, 0xe8} \
21 }
22
23 typedef struct _EFI_BLOCK_IO_CRYPTO_PROTOCOL EFI_BLOCK_IO_CRYPTO_PROTOCOL;
24
25 ///
26 /// The struct of Block I/O Crypto Token.
27 ///
28 typedef struct {
29 //
30 // If Event is NULL, then blocking I/O is performed. If Event is not NULL and
31 // non-blocking I/O is supported, then non-blocking I/O is performed, and
32 // Event will be signaled when the read request is completed and data was
33 // decrypted (when Index was specified).
34 //
35 EFI_EVENT Event;
36 //
37 // Defines whether or not the signaled event encountered an error.
38 //
39 EFI_STATUS TransactionStatus;
40 } EFI_BLOCK_IO_CRYPTO_TOKEN;
41
42 typedef struct {
43 //
44 // GUID of the algorithm.
45 //
46 EFI_GUID Algorithm;
47 //
48 // Specifies KeySizein bits used with this Algorithm.
49 //
50 UINT64 KeySize;
51 //
52 // Specifies bitmask of block sizes supported by this algorithm.
53 // Bit j being set means that 2^j bytes crypto block size is supported.
54 //
55 UINT64 CryptoBlockSizeBitMask;
56 } EFI_BLOCK_IO_CRYPTO_CAPABILITY;
57
58 ///
59 /// EFI_BLOCK_IO_CRYPTO_IV_INPUT structure is used as a common header in CryptoIvInput
60 /// parameters passed to the ReadExtended and WriteExtended methods for Inline
61 /// Cryptographic Interface.
62 /// Its purpose is to pass size of the entire CryptoIvInputparameter memory buffer to
63 /// the Inline Cryptographic Interface.
64 ///
65 typedef struct {
66 UINT64 InputSize;
67 } EFI_BLOCK_IO_CRYPTO_IV_INPUT;
68
69 #define EFI_BLOCK_IO_CRYPTO_ALGO_GUID_AES_XTS \
70 { \
71 0x2f87ba6a, 0x5c04, 0x4385, {0xa7, 0x80, 0xf3, 0xbf, 0x78, 0xa9, 0x7b, 0xec} \
72 }
73
74 extern EFI_GUID gEfiBlockIoCryptoAlgoAesXtsGuid;
75
76 typedef struct {
77 EFI_BLOCK_IO_CRYPTO_IV_INPUT Header;
78 UINT64 CryptoBlockNumber;
79 UINT64 CryptoBlockByteSize;
80 } EFI_BLOCK_IO_CRYPTO_IV_INPUT_AES_XTS;
81
82 #define EFI_BLOCK_IO_CRYPTO_ALGO_GUID_AES_CBC_MICROSOFT_BITLOCKER \
83 { \
84 0x689e4c62, 0x70bf, 0x4cf3, {0x88, 0xbb, 0x33, 0xb3, 0x18, 0x26, 0x86, 0x70} \
85 }
86
87 extern EFI_GUID gEfiBlockIoCryptoAlgoAesCbcMsBitlockerGuid;
88
89 typedef struct {
90 EFI_BLOCK_IO_CRYPTO_IV_INPUT Header;
91 UINT64 CryptoBlockByteOffset;
92 UINT64 CryptoBlockByteSize;
93 } EFI_BLOCK_IO_CRYPTO_IV_INPUT_AES_CBC_MICROSOFT_BITLOCKER;
94
95 #define EFI_BLOCK_IO_CRYPTO_INDEX_ANY 0xFFFFFFFFFFFFFFFF
96
97 typedef struct {
98 //
99 // Is inline cryptographic capability supported on this device.
100 //
101 BOOLEAN Supported;
102 //
103 // Maximum number of keys that can be configured at the same time.
104 //
105 UINT64 KeyCount;
106 //
107 // Number of supported capabilities.
108 //
109 UINT64 CapabilityCount;
110 //
111 // Array of supported capabilities.
112 //
113 EFI_BLOCK_IO_CRYPTO_CAPABILITY Capabilities[1];
114 } EFI_BLOCK_IO_CRYPTO_CAPABILITIES;
115
116 typedef struct {
117 //
118 // Configuration table index. A special Index EFI_BLOCK_IO_CRYPTO_INDEX_ANY can be
119 // used to set any available entry in the configuration table.
120 //
121 UINT64 Index;
122 //
123 // Identifies the owner of the configuration table entry. Entry can also be used
124 // with the Nil value to clear key from the configuration table index.
125 //
126 EFI_GUID KeyOwnerGuid;
127 //
128 // A supported capability to be used. The CryptoBlockSizeBitMask field of the
129 // structure should have only one bit set from the supported mask.
130 //
131 EFI_BLOCK_IO_CRYPTO_CAPABILITY Capability;
132 //
133 // Pointer to the key. The size of the key is defined by the KeySize field of
134 // the capability specified by the Capability parameter.
135 //
136 VOID *CryptoKey;
137 } EFI_BLOCK_IO_CRYPTO_CONFIGURATION_TABLE_ENTRY;
138
139 typedef struct {
140 //
141 // Configuration table index.
142 //
143 UINT64 Index;
144 //
145 // Identifies the current owner of the entry.
146 //
147 EFI_GUID KeyOwnerGuid;
148 //
149 // The capability to be used. The CryptoBlockSizeBitMask field of the structure
150 // has only one bit set from the supported mask.
151 //
152 EFI_BLOCK_IO_CRYPTO_CAPABILITY Capability;
153 } EFI_BLOCK_IO_CRYPTO_RESPONSE_CONFIGURATION_ENTRY;
154
155 /**
156 Reset the block device hardware.
157
158 The Reset() function resets the block device hardware.
159
160 As part of the initialization process, the firmware/device will make a quick but
161 reasonable attempt to verify that the device is functioning.
162
163 If the ExtendedVerificationflag is TRUE the firmware may take an extended amount
164 of time to verify the device is operating on reset. Otherwise the reset operation
165 is to occur as quickly as possible.
166
167 The hardware verification process is not defined by this specification and is left
168 up to the platform firmware or driver to implement.
169
170 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
171 @param[in] ExtendedVerification Indicates that the driver may perform a more exhausive
172 verification operation of the device during reset.
173
174 @retval EFI_SUCCESS The block device was reset.
175 @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could
176 not be reset.
177 @retval EFI_INVALID_PARAMETER This is NULL.
178
179 **/
180 typedef
181 EFI_STATUS
182 (EFIAPI *EFI_BLOCK_IO_CRYPTO_RESET) (
183 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
184 IN BOOLEAN ExtendedVerification
185 );
186
187 /**
188 Get the capabilities of the underlying inline cryptographic interface.
189
190 The GetCapabilities() function determines whether pre-OS controllable inline crypto
191 is supported by the system for the current disk and, if so, returns the capabilities
192 of the crypto engine.
193
194 The caller is responsible for providing the Capabilities structure with a sufficient
195 number of entries.
196
197 If the structure is too small, the EFI_BUFFER_TOO_SMALL error code is returned and the
198 CapabilityCount field contains the number of entries needed to contain the capabilities.
199
200 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
201 @param[out] Capabilities Pointer to the EFI_BLOCK_IO_CRYPTO_CAPABILITIES structure.
202
203 @retval EFI_SUCCESS The ICI is ready for use.
204 @retval EFI_BUFFER_TOO_SMALL The Capabilities structure was too small. The number of
205 entries needed is returned in the CapabilityCount field
206 of the structure.
207 @retval EFI_NO_RESPONSE No response was received from the ICI.
208 @retval EFI_DEVICE_ERROR An error occurred when attempting to access the ICI.
209 @retval EFI_INVALID_PARAMETER This is NULL.
210 @retval EFI_INVALID_PARAMETER Capabilities is NULL.
211
212 **/
213 typedef
214 EFI_STATUS
215 (EFIAPI *EFI_BLOCK_IO_CRYPTO_GET_CAPABILITIES) (
216 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
217 OUT EFI_BLOCK_IO_CRYPTO_CAPABILITIES *Capabilities
218 );
219
220 /**
221 Set the configuration of the underlying inline cryptographic interface.
222
223 The SetConfiguration() function allows the user to set the current configuration of the
224 inline cryptographic interface and should be called before attempting any crypto operations.
225
226 This configures the configuration table entries with algorithms, key sizes and keys. Each
227 configured entry can later be referred to by index at the time of storage transaction.
228
229 The configuration table index will refer to the combination ofKeyOwnerGuid, Algorithm, and
230 CryptoKey.
231
232 KeyOwnerGuid identifies the component taking ownership of the entry. It helps components to
233 identify their own entries, cooperate with other owner components, and avoid conflicts. This
234 Guid identifier is there to help coordination between cooperating components and not a security
235 or synchronization feature. The Nil GUID can be used by a component to release use of entry
236 owned. It is also used to identify potentially available entries (see GetConfiguration).
237
238 CryptoKey specifies algorithm-specific key material to use within parameters of selected crypto
239 capability.
240
241 This function is called infrequently typically once, on device start, before IO starts. It
242 can be called at later times in cases the number of keysused on the drive is higher than what
243 can be configured at a time or a new key has to be added.
244
245 Components setting or changing an entry or entries for a given index or indices must ensure
246 that IO referencing affected indices is temporarily blocked (run-down) at the time of change.
247
248 Indices parameters in each parameter table entry allow to set only a portion of the available
249 table entries in the crypto module anywhere from single entry to entire table supported.
250
251 If corresponding table entry or entries being set are already in use by another owner the call
252 should be failed and none of the entries should be modified. The interface implementation must
253 enforce atomicity of this operation (should either succeed fully or fail completely without
254 modifying state).
255
256 Note that components using GetConfiguration command to discover available entries should be
257 prepared that by the time of calling SetConfiguration the previously available entry may have
258 become occupied. Such components should be prepared to re-try the sequence of operations.
259
260 Alternatively EFI_BLOCK_IO_CRYPTO_INDEX_ANY can be used to have the implementation discover
261 and allocate available,if any, indices atomically.
262
263 An optional ResultingTable pointer can be provided by the caller to receive the newly configured
264 entries. The array provided by the caller must have at least ConfigurationCount of entries.
265
266 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
267 @param[in] ConfigurationCount Number of entries being configured with this call.
268 @param[in] ConfigurationTable Pointer to a table used to populate the configuration table.
269 @param[out] ResultingTable Optional pointer to a table that receives the newly configured
270 entries.
271
272 @retval EFI_SUCCESS The ICI is ready for use.
273 @retval EFI_NO_RESPONSE No response was received from the ICI.
274 @retval EFI_DEVICE_ERROR An error occurred when attempting to access the ICI.
275 @retval EFI_INVALID_PARAMETER This is NULL.
276 @retval EFI_INVALID_PARAMETER ConfigurationTable is NULL.
277 @retval EFI_INVALID_PARAMETER ConfigurationCount is 0.
278 @retval EFI_OUT_OF_RESOURCES Could not find the requested number of available entries in the
279 configuration table.
280
281 **/
282 typedef
283 EFI_STATUS
284 (EFIAPI *EFI_BLOCK_IO_CRYPTO_SET_CONFIGURATION) (
285 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
286 IN UINT64 ConfigurationCount,
287 IN EFI_BLOCK_IO_CRYPTO_CONFIGURATION_TABLE_ENTRY *ConfigurationTable,
288 OUT EFI_BLOCK_IO_CRYPTO_RESPONSE_CONFIGURATION_ENTRY *ResultingTable OPTIONAL
289 );
290
291 /**
292 Get the configuration of the underlying inline cryptographic interface.
293
294 The GetConfiguration() function allows the user to get the configuration of the inline
295 cryptographic interface.
296
297 Retrieves, entirely or partially, the currently configured key table. Note that the keys
298 themselves are not retrieved, but rather just indices, owner GUIDs and capabilities.
299
300 If fewer entries than specified by ConfigurationCount are returned, the Index field of the
301 unused entries is set to EFI_BLOCK_IO_CRYPTO_INDEX_ANY.
302
303 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
304 @param[in] StartIndex Configuration table index at which to start the configuration
305 query.
306 @param[in] ConfigurationCount Number of entries to return in the response table.
307 @param[in] KeyOwnerGuid Optional parameter to filter response down to entries with a
308 given owner. A pointer to the Nil value can be used to return
309 available entries. Set to NULL when no owner filtering is required.
310 @param[out] ConfigurationTable Table of configured configuration table entries (with no CryptoKey
311 returned): configuration table index, KeyOwnerGuid, Capability.
312 Should have sufficient space to store up to ConfigurationCount
313 entries.
314
315 @retval EFI_SUCCESS The ICI is ready for use.
316 @retval EFI_NO_RESPONSE No response was received from the ICI.
317 @retval EFI_DEVICE_ERROR An error occurred when attempting to access the ICI.
318 @retval EFI_INVALID_PARAMETER This is NULL.
319 @retval EFI_INVALID_PARAMETER Configuration table is NULL.
320 @retval EFI_INVALID_PARAMETER StartIndex is out of bounds.
321
322 **/
323 typedef
324 EFI_STATUS
325 (EFIAPI *EFI_BLOCK_IO_CRYPTO_GET_CONFIGURATION) (
326 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
327 IN UINT64 StartIndex,
328 IN UINT64 ConfigurationCount,
329 IN EFI_GUID *KeyOwnerGuid OPTIONAL,
330 OUT EFI_BLOCK_IO_CRYPTO_RESPONSE_CONFIGURATION_ENTRY *ConfigurationTable
331 );
332
333 /**
334 Reads the requested number of blocks from the device and optionally decrypts
335 them inline.
336
337 TheReadExtended() function allows the caller to perform a storage device read
338 operation. The function reads the requested number of blocks from the device
339 and then if Index is specified decrypts them inline. All the blocks are read
340 and decrypted (if decryption requested), or an error is returned.
341
342 If there is no media in the device, the function returns EFI_NO_MEDIA. If the
343 MediaId is not the ID for the current media in the device, the function returns
344 EFI_MEDIA_CHANGED.
345
346 If EFI_DEVICE_ERROR, EFI_NO_MEDIA, or EFI_MEDIA_CHANGED is returned and nonblocking
347 I/O is being used, the Event associated with this request will not be signaled.
348
349 In addition to standard storage transaction parameters (LBA, IO size, and buffer),
350 this command will also specify a configuration table Index and CryptoIvInput
351 when data has to be decrypted inline by the controller after being read from
352 the storage device. If an Index parameter is not specified, no decryption is
353 performed.
354
355 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
356 @param[in] MediaId The media ID that the read request is for.
357 @param[in] LBA The starting logical block address to read from on
358 the device.
359 @param[in, out] Token A pointer to the token associated with the transaction.
360 @param[in] BufferSize The size of the Buffer in bytes. This must be a multiple
361 of the intrinsic block size of the device.
362 @param[out] Buffer A pointer to the destination buffer for the data. The
363 caller is responsible for either having implicit or
364 explicit ownership of the buffer.
365 @param[in] Index A pointer to the configuration table index. This is
366 optional.
367 @param[in] CryptoIvInput A pointer to a buffer that contains additional
368 cryptographic parameters as required by the capability
369 referenced by the configuration table index, such as
370 cryptographic initialization vector.
371
372 @retval EFI_SUCCESS The read request was queued if Token-> Event is not NULL.
373 The data was read correctly from the device if the
374 Token->Event is NULL.
375 @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform
376 the read operation and/or decryption operation.
377 @retval EFI_NO_MEDIA There is no media in the device.
378 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
379 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the intrinsic
380 block size of the device.
381 @retval EFI_INVALID_PARAMETER This is NULL, or the read request contains LBAs that are
382 not valid, or the buffer is not on proper alignment.
383 @retval EFI_INVALID_PARAMETER CryptoIvInput is incorrect.
384 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
385 resources.
386
387 **/
388 typedef
389 EFI_STATUS
390 (EFIAPI *EFI_BLOCK_IO_CRYPTO_READ_EXTENDED) (
391 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
392 IN UINT32 MediaId,
393 IN EFI_LBA LBA,
394 IN OUT EFI_BLOCK_IO_CRYPTO_TOKEN *Token,
395 IN UINT64 BufferSize,
396 OUT VOID *Buffer,
397 IN UINT64 *Index OPTIONAL,
398 IN VOID *CryptoIvInput OPTIONAL
399 );
400
401 /**
402 Optionally encrypts a specified number of blocks inline and then writes to the
403 device.
404
405 The WriteExtended() function allows the caller to perform a storage device write
406 operation. The function encrypts the requested number of blocks inline if Index
407 is specified and then writes them to the device. All the blocks are encrypted
408 (if encryption requested) and written, or an error is returned.
409
410 If there is no media in the device, the function returns EFI_NO_MEDIA. If the
411 MediaId is not the ID for the current media in the device, the function returns
412 EFI_MEDIA_CHANGED.
413
414 If EFI_DEVICE_ERROR, EFI_NO_MEDIA, or EFI_MEDIA_CHANGED is returned and nonblocking
415 I/O is being used, the Event associated with this request will not be signaled.
416
417 In addition to standard storage transaction parameters (LBA, IO size, and buffer),
418 this command will also specify a configuration table Index and a CryptoIvInput
419 when data has to be decrypted inline by the controller before being written to
420 the storage device. If no Index parameter is specified, no encryption is performed.
421
422 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
423 @param[in] MediaId The media ID that the read request is for.
424 @param[in] LBA The starting logical block address to read from on
425 the device.
426 @param[in, out] Token A pointer to the token associated with the transaction.
427 @param[in] BufferSize The size of the Buffer in bytes. This must be a multiple
428 of the intrinsic block size of the device.
429 @param[in] Buffer A pointer to the source buffer for the data.
430 @param[in] Index A pointer to the configuration table index. This is
431 optional.
432 @param[in] CryptoIvInput A pointer to a buffer that contains additional
433 cryptographic parameters as required by the capability
434 referenced by the configuration table index, such as
435 cryptographic initialization vector.
436
437 @retval EFI_SUCCESS The request to encrypt (optionally) and write was queued
438 if Event is not NULL. The data was encrypted (optionally)
439 and written correctly to the device if the Event is NULL.
440 @retval EFI_WRITE_PROTECTED The device cannot be written to.
441 @retval EFI_NO_MEDIA There is no media in the device.
442 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
443 @retval EFI_DEVICE_ERROR The device reported an error while attempting to encrypt
444 blocks or to perform the write operation.
445 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the intrinsic
446 block size of the device.
447 @retval EFI_INVALID_PARAMETER This is NULL, or the write request contains LBAs that are
448 not valid, or the buffer is not on proper alignment.
449 @retval EFI_INVALID_PARAMETER CryptoIvInput is incorrect.
450 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
451 resources.
452
453 **/
454 typedef
455 EFI_STATUS
456 (EFIAPI *EFI_BLOCK_IO_CRYPTO_WRITE_EXTENDED) (
457 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
458 IN UINT32 MediaId,
459 IN EFI_LBA LBA,
460 IN OUT EFI_BLOCK_IO_CRYPTO_TOKEN *Token,
461 IN UINT64 BufferSize,
462 IN VOID *Buffer,
463 IN UINT64 *Index OPTIONAL,
464 IN VOID *CryptoIvInput OPTIONAL
465 );
466
467 /**
468 Flushes all modified data toa physical block device.
469
470 The FlushBlocks() function flushes all modified data to the physical block device.
471 Any modified data that has to be encrypted must have been already encrypted as a
472 part of WriteExtended() operation - inline crypto operation cannot be a part of
473 flush operation.
474
475 All data written to the device prior to the flush must be physically written before
476 returning EFI_SUCCESS from this function. This would include any cached data the
477 driver may have cached, and cached data the device may have cached. A flush may
478 cause a read request following the flush to force a device access.
479
480 If EFI_DEVICE_ERROR, EFI_NO_MEDIA, EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is
481 returned and non-blocking I/O is being used, the Event associated with this request
482 will not be signaled.
483
484 @param[in] This Pointer to the EFI_BLOCK_IO_CRYPTO_PROTOCOL instance.
485 @param[in, out] Token A pointer to the token associated with the transaction.
486
487 @retval EFI_SUCCESS The flush request was queued if Event is not NULL. All
488 outstanding data was written correctly to the device if
489 the Event is NULL.
490 @retval EFI_DEVICE_ERROR The device reported an error while attempting to write data.
491 @retval EFI_WRITE_PROTECTED The device cannot be written to.
492 @retval EFI_NO_MEDIA There is no media in the device.
493 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
494 @retval EFI_INVALID_PARAMETER This is NULL.
495 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
496 resources.
497
498 **/
499 typedef
500 EFI_STATUS
501 (EFIAPI *EFI_BLOCK_IO_CRYPTO_FLUSH) (
502 IN EFI_BLOCK_IO_CRYPTO_PROTOCOL *This,
503 IN OUT EFI_BLOCK_IO_CRYPTO_TOKEN *Token
504 );
505
506 ///
507 /// The EFI_BLOCK_IO_CRYPTO_PROTOCOL defines a UEFI protocol that can be used by UEFI
508 /// drivers and applications to perform block encryption on a storage device, such as UFS.
509 ///
510 struct _EFI_BLOCK_IO_CRYPTO_PROTOCOL {
511 EFI_BLOCK_IO_MEDIA *Media;
512 EFI_BLOCK_IO_CRYPTO_RESET Reset;
513 EFI_BLOCK_IO_CRYPTO_GET_CAPABILITIES GetCapabilities;
514 EFI_BLOCK_IO_CRYPTO_SET_CONFIGURATION SetConfiguration;
515 EFI_BLOCK_IO_CRYPTO_GET_CONFIGURATION GetConfiguration;
516 EFI_BLOCK_IO_CRYPTO_READ_EXTENDED ReadExtended;
517 EFI_BLOCK_IO_CRYPTO_WRITE_EXTENDED WriteExtended;
518 EFI_BLOCK_IO_CRYPTO_FLUSH FlushBlocks;
519 };
520
521 extern EFI_GUID gEfiBlockIoCryptoProtocolGuid;
522
523 #endif
524