Skip to main content

Crypto operators

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.


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.