--- title: "Crypto operators" source_url: https://dev.digicert.com/trustcore-sdk/nanocap/crypto-operators.html --- Crypto operators are components that perform specific cryptographic operations. These operators are important elements in cryptographic systems and libraries that provide an abstraction layer. The abstraction layer enables applications to utilize cryptographic algorithms without directly handling the underlying implementation details. ## Core structure definitions The first argument to any operator is the **object**. For **symmetric** algorithms, `MocSymCtx` is used. Review the following example: ``` typedef struct MocSymContext {  ubyte4         localType;  MSymOperator   SymOperator;  void          *pLocalData;  ubyte          state; } MocSymContext; ``` For **asymmetric** algorithms, `MocAsymKey` is used. Review the following example: ``` typedef struct MocAsymmetricKey {  ubyte4         localType;  MocCtx         pMocCtx;  MKeyOperator   KeyOperator;  void          *pKeyData; } MocAsymmetricKey; ``` ## Operator creation NanoCAP's API handles the packing and unpacking of operation-specific data structures, which allows callers not to be overly familiar with op-code specifics. The following example displays a NanoCAP function to create a new MocSymCtx structure where: - The `SymOperator` parameter represents a function pointer to a symmetric operator. - The `pOperatorInfo` parameter represents the corresponding information that the operator expects during the creation process. - The `pMocCtx` parameter represents the cryptographic context. - The `ppNewCtx` parameter represents the pointer to allocate and receive the new `MocSymCtx` object. ``` MSTATUS CRYPTO_createMocSymCtx (        MSymOperator SymOperator,        Void *pOperatorInfo,        MocCtx pMocCtx,        MocSymCtx *ppNewCtx    ); ``` Based on the above example: 1. The `CRYPTO_createMocSymCtx` implementation allocates memory for `MocSymCtx`. 2. A request is made to the operator to create itself using the `MOC_SYM_OP_CREATE` op code. 3. The operator implementation configures the local type and assigns the function pointer to the `SymOperator` field within `MocSymCtx`. 4. The operator allocates its own local data structure and stores it in the `pLocalData` or `pKeyData` field. This data structure may include key data, contexts, hardware handles, or other relevant information. 5. When the object has completed its operations, a higher-level free function `(MOC_SYM_OP_FREE` or `MOC_ASYM_OP_FREE`) is used to call the operator. 6. The operator frees any memory allocated for local data and closes the connection. The operator does not directly handle `MocSymCtx` or `MocAsymKey`; the higher-level function is responsible for freeing that memory. ## Operator usage While the creation of an operator is tied closely with its implementation, the actual purpose of an operator (to perform cryptographic operations) is completely untied. In the following example, a digest operation is updated after `MocSymCtx` has been created. Additionally: - `MocSymCtx pSymCtx` represents the cryptographic context for symmetric operations. - `ubyte *pDataToDigest` represents the data to be digested. - `ubyte4 dataToDigestLen` represents the length of the data to be digested. ``` MSTATUS CRYPTO_digestUpdate (        MocSymCtx pSymCtx,        ubyte *pDataToDigest,        ubyte4 dataToDigestLen    ); ``` Based on the above example, building a symmetric operator to digest data requires implementing the `MOC_SYM_OP_DIGEST_UPDATE` op code. The operator knows to de-reference the input information as a pointer to the `MSymOperatorData` structure, which is defined in the header file `capsym.h`. The implementing operator can then use the input data to perform the cryptographic operation. > **Info** > > Not all operators support every op code. > > For example, an operator implementing SHA256 would not implement any `MOC_SYM_OP_MAC_*` op codes. The `CRYPTO_digestUpdate` function simplifies the process of digesting data. It transforms the digesting object and the data into a request directed to the object, utilizing the `MOC_SYM_OP_DIGEST_UPDATE` op code. This flexibility allows callers to digest data using any valid digest algorithm implementation within NanoCAP.