#include "skpm_service_key.h"
#include "skpm.h"
#include "skpm_tls.h"
#include "skpm_util.h"

uint8_t sDrkCert[MAX_CERT_SIZE] = {0,};
uint16_t sDrkCertLen = 0;

uint8_t sServiceCert[MAX_CERT_SIZE] = {0,};
uint16_t sServiceCertLen = 0;

uint8_t sServiceKey[MAX_CERT_SIZE] = {0,};
uint16_t sServiceKeyLen = 0;

extern tls_session_info_t sOtaTlsSession;

static int32_t parseSKPMServiceKeyBlob() {
    int32_t ret = RET_SUCCESS;
    uint32_t offset = 0;

    LOGD("parseSKPMServiceKeyBlob Started");

    memset((uint8_t *)&sOtaTlsSession, 0, sizeof(tls_session_info_t));

    if (sServiceKey[offset] == 0x30) {
        offset += 4;
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 3;
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.modulus, sizeof(sOtaTlsSession.serviceRsaKey.modulus), &(sOtaTlsSession.serviceRsaKey.modulus_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.modulus", sOtaTlsSession.serviceRsaKey.modulus, sOtaTlsSession.serviceRsaKey.modulus_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.publicExponent, sizeof(sOtaTlsSession.serviceRsaKey.publicExponent), &(sOtaTlsSession.serviceRsaKey.publicExponent_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.publicExponent", sOtaTlsSession.serviceRsaKey.publicExponent, sOtaTlsSession.serviceRsaKey.publicExponent_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.privateExponent, sizeof(sOtaTlsSession.serviceRsaKey.privateExponent), &(sOtaTlsSession.serviceRsaKey.privateExponent_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.privateExponent", sOtaTlsSession.serviceRsaKey.privateExponent, sOtaTlsSession.serviceRsaKey.privateExponent_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }
    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }
    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.prime1, sizeof(sOtaTlsSession.serviceRsaKey.prime1), &(sOtaTlsSession.serviceRsaKey.prime1_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.prime1", sOtaTlsSession.serviceRsaKey.prime1, sOtaTlsSession.serviceRsaKey.prime1_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.prime2, sizeof(sOtaTlsSession.serviceRsaKey.prime2), &(sOtaTlsSession.serviceRsaKey.prime2_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.prime2", sOtaTlsSession.serviceRsaKey.prime2, sOtaTlsSession.serviceRsaKey.prime2_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.exponent1, sizeof(sOtaTlsSession.serviceRsaKey.exponent1), &(sOtaTlsSession.serviceRsaKey.exponent1_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.exponent1", sOtaTlsSession.serviceRsaKey.exponent1, sOtaTlsSession.serviceRsaKey.exponent1_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.exponent2, sizeof(sOtaTlsSession.serviceRsaKey.exponent2), &(sOtaTlsSession.serviceRsaKey.exponent2_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.exponent2", sOtaTlsSession.serviceRsaKey.exponent2, sOtaTlsSession.serviceRsaKey.exponent2_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    if (offset >= sizeof(sServiceKey)) {
        LOGE("offset is over the sServiceKey buffer size");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (sServiceKey[offset] == 0x02) {
        offset += 1;
        if (offset >= sizeof(sServiceKey)) {
            LOGE("offset is over the sServiceKey buffer size");
            ret = RET_ERR_BUFFER_NOT_ENOUGH;
            goto error;
        }
        if ((ret = parseTlvData(sServiceKey + offset, sServiceKeyLen - offset, sOtaTlsSession.serviceRsaKey.coefficient, sizeof(sOtaTlsSession.serviceRsaKey.coefficient), &(sOtaTlsSession.serviceRsaKey.coefficient_size))) < 0) {
            goto error;
        }
        offset += ret;
        hex_print_tag_debug("sOtaTlsSession.serviceRsaKey.coefficient", sOtaTlsSession.serviceRsaKey.coefficient, sOtaTlsSession.serviceRsaKey.coefficient_size);
    } else {
        LOGE("ERROR : PrivateKey tag not found");
        ret = RET_ERR_SERVICE_KEY_PARSING_FAIL;
        goto error;
    }

    ret = RET_SUCCESS;

error:
    secure_memclear(sServiceKey, sizeof(sServiceKey));

    return ret;
}

static int32_t parseSKPMServiceKey(uint8_t* unwrapData, uint16_t unwrapDataLen) {
    uint8_t drkCert[MAX_CERT_SIZE] = {0x00,};
    uint16_t drkCertSize = 0;

    uint8_t skpmServiceKeyCert[MAX_CERT_SIZE] = {0x00,};
    uint16_t skpmServiceKeyCertSize = 0;

    uint8_t privateKey[MAX_CERT_SIZE] = {0x00,};
    uint16_t privateKeySize = 0;

    uint32_t offset = 0;
    uint16_t realDrkLen = 0;

    // Device Root Key Cert
    if (unwrapData[offset] == 0x01) {
        if (offset + 1 + 2 >= unwrapDataLen) {
            LOGE("drkCertSize is over the buffer.");
            return RET_ERR_BUFFER_NOT_ENOUGH;
        }
        memcpy(&drkCertSize, unwrapData + offset + 1, 2);
        offset = offset + 1 + 2;
        if (offset >= unwrapDataLen) {
            LOGE("offset is over the buffer.");
            return RET_ERR_BUFFER_NOT_ENOUGH;
        }
        if (drkCertSize > sizeof(drkCert)) {
            LOGE("drkCert is over the buffer.");
            return RET_ERR_BUFFER_NOT_ENOUGH;
        }
        if (drkCertSize == 0) {
            LOGE("drkCert is zero");
            return RET_ERR_WRONG_INPUT_FORMAT;
        }
        memcpy(drkCert, unwrapData + offset, drkCertSize);
        hex_print_tag_debug("DRK Cert", drkCert, drkCertSize);
        offset = offset + drkCertSize;
        if (offset >= unwrapDataLen) {
            LOGE("offset is over the buffer.");
            return RET_ERR_BUFFER_NOT_ENOUGH;
        }

        // SKPM Service Key Cert
        if (unwrapData[offset] == 0x01) {
            if (offset + 1 + 2 >= unwrapDataLen) {
                LOGE("skpmServiceKeyCertSize is over the buffer.");
                return RET_ERR_BUFFER_NOT_ENOUGH;
            }
            memcpy(&skpmServiceKeyCertSize, unwrapData + offset + 1, 2);
            offset = offset + 1 + 2;
            if (offset >= unwrapDataLen) {
                LOGE("offset is over the buffer.");
                return RET_ERR_BUFFER_NOT_ENOUGH;
            }
            if (skpmServiceKeyCertSize > sizeof(skpmServiceKeyCert)) {
                LOGE("skpmServiceKeyCert is over the buffer.");
                return RET_ERR_BUFFER_NOT_ENOUGH;
            }
            if (skpmServiceKeyCertSize == 0) {
                LOGE("skpmServiceKeyCert is zero");
                return RET_ERR_WRONG_INPUT_FORMAT;
            }
            memcpy(skpmServiceKeyCert, unwrapData + offset, skpmServiceKeyCertSize);
            hex_print_tag_debug("Service Key Cert", skpmServiceKeyCert, skpmServiceKeyCertSize);
            offset = offset + skpmServiceKeyCertSize;
            if (offset >= unwrapDataLen) {
                LOGE("offset is over the buffer.");
                return RET_ERR_BUFFER_NOT_ENOUGH;
            }

            // Private Key
            if (unwrapData[offset] == 0x03) {
                if (offset + 1 + 2 >= unwrapDataLen) {
                    LOGE("privateKeySize is over the buffer.");
                    return RET_ERR_BUFFER_NOT_ENOUGH;
                }
                memcpy(&privateKeySize, unwrapData + offset + 1, 2);
                offset = offset + 1 + 2;
                if (offset >= unwrapDataLen) {
                    LOGE("offset is over the buffer.");
                    return RET_ERR_BUFFER_NOT_ENOUGH;
                }
                if (privateKeySize > sizeof(privateKey)) {
                    LOGE("privateKey is over the buffer.");
                    return RET_ERR_BUFFER_NOT_ENOUGH;
                }
                if (privateKeySize == 0) {
                    LOGE("privateKey is zero");
                    return RET_ERR_WRONG_INPUT_FORMAT;
                }
                memcpy(privateKey, unwrapData + offset, privateKeySize);
                hex_print_tag_debug("Private Key Structure", privateKey, privateKeySize);
                offset = offset + privateKeySize;
                if (offset >= unwrapDataLen) {
                    LOGE("offset is over the buffer.");
                    return RET_ERR_BUFFER_NOT_ENOUGH;
                }
            } else {
                LOGE("ERROR : PrivateKey tag not found");
                return RET_ERR_SERVICE_KEY_PARSING_FAIL;
            }
        } else {
            LOGE("ERROR : SKPM ServiceKey CERT tag not found");
            return RET_ERR_SERVICE_KEY_PARSING_FAIL;
        }
    } else {
        LOGE("ERROR : DRK CERT tag not found");
        return RET_ERR_SERVICE_KEY_PARSING_FAIL;
    }

    realDrkLen = drkCert[2];
    realDrkLen = realDrkLen << 8;
    realDrkLen |= drkCert[3];
    realDrkLen += 4;
    if (realDrkLen > sizeof(sDrkCert)) {
        LOGE("sDrkCert is over the buffer.");
        return RET_ERR_BUFFER_NOT_ENOUGH;
    }
    if (realDrkLen == 0) {
        LOGE("drkCert is zero");
        return RET_ERR_WRONG_INPUT_FORMAT;
    }
    memcpy(sDrkCert, drkCert, realDrkLen);
    sDrkCertLen = realDrkLen;
    if (skpmServiceKeyCertSize > sizeof(sServiceCert)) {
        LOGE("sServiceCert is over the buffer.");
        return RET_ERR_BUFFER_NOT_ENOUGH;
    }
    if (skpmServiceKeyCertSize == 0) {
        LOGE("skpmServiceKeyCert is zero");
        return RET_ERR_WRONG_INPUT_FORMAT;
    }
    memcpy(sServiceCert, skpmServiceKeyCert, skpmServiceKeyCertSize);
    sServiceCertLen = skpmServiceKeyCertSize;
    if (privateKeySize > sizeof(sServiceKey)) {
        LOGE("sServiceKey is over the buffer.");
        return RET_ERR_BUFFER_NOT_ENOUGH;
    }
    if (privateKeySize == 0) {
        LOGE("privateKey is zero");
        return RET_ERR_WRONG_INPUT_FORMAT;
    }
    memcpy(sServiceKey, privateKey, privateKeySize);
    sServiceKeyLen = privateKeySize;

    secure_memclear(privateKey, sizeof(privateKey));

    return parseSKPMServiceKeyBlob();
}

void rewrapSKPMServiceKey(p_cmd_t cmd, p_rsp_t rsp) {
    int32_t ret = RET_SUCCESS;

    uint8_t input[WRAPPED_SERVICE_KEY_BLOB_SIZE] = {0, };
    uint32_t inputSize;
    uint8_t output[WRAPPED_SERVICE_KEY_BLOB_SIZE] = {0, };
    uint32_t outputSize = WRAPPED_SERVICE_KEY_BLOB_SIZE;
    uint8_t rewrappedData[WRAPPED_SERVICE_KEY_BLOB_SIZE] = {0, };
    uint32_t rewrappedDataSize = WRAPPED_SERVICE_KEY_BLOB_SIZE;
#ifdef USE_BLOWFISH
    const uint8_t DRK_TID[TID_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x4b, 0x4d};
#endif
#ifdef USE_QSEE
    const uint8_t DRK_TID[QSEE_MESSAGE_APP_NAME_MAX_LEN] = "skm";
#endif

    LOGD("rewrapSKPMServiceKey started");
    inputSize = cmd->dataLen;
    if (inputSize > WRAPPED_SERVICE_KEY_BLOB_SIZE) {
        LOGE("Input data is over the buffer.");
        return ;
    }
    memcpy(input, cmd->data, inputSize);

    //hex_print_tag_debug("input", input, inputSize);
#if defined(USE_BLOWFISH) || defined(USE_QSEE)
    ret = unwrap_secure_object(DRK_TID, input, inputSize, output, &outputSize);
#else
    ret = unwrap_secure_object(input, inputSize, output, &outputSize);
#endif
    if (ret == RET_SUCCESS) {
        //hex_print_tag_debug("output", output, outputSize);
        ret = wrapInternalData(SECURE_OBJECT_TYPE_SERVICE_KEY, output, outputSize, rewrappedData, &rewrappedDataSize);
        if (ret != RET_SUCCESS) {
            LOGE("wrap_secure_object failed.");
            ret = RET_ERR_DATA_WRAPPING_FAIL;
            goto error;

        } else {
            if (rewrappedDataSize == 0) {
                LOGE("rewrappedData is zero");
                ret =  RET_ERR_WRONG_INPUT_FORMAT;
                goto error;
            }
            memcpy(rsp->data, rewrappedData, rewrappedDataSize);
            rsp->dataLen = rewrappedDataSize;
            ret = RET_SUCCESS;
        }
    } else {
        LOGE("unwrap_secure_object failed !!, ret : %x", ret);
        ret = RET_ERR_DATA_UNWRAPPING_FAIL;
        goto error;
    }

error:
    LOGD("rewrapSKPMServiceKey end : ret = %d", ret);

    rsp->ret = ret;
}

void unwrapRewrappedSKPMServiceKey(p_cmd_t cmd, p_rsp_t rsp) {
    int32_t ret = RET_SUCCESS;

    uint8_t input[WRAPPED_SERVICE_KEY_BLOB_SIZE] = {0, };
    uint32_t inputSize;
    uint8_t output[WRAPPED_SERVICE_KEY_BLOB_SIZE] = {0, };
    uint32_t outputSize = WRAPPED_SERVICE_KEY_BLOB_SIZE;

    uint8_t wrappedKeyInfo[WRAPPED_KEY_INFO_SIZE];
    uint32_t wrappedKeyInfoSize;

    uint32_t current_pos;

    LOGD("unwrapRewrappedSKPMServiceKey started");
    inputSize = cmd->dataLen;

    if (inputSize > sizeof(input)) {
        LOGE("input is over the buffer.");
        ret = RET_ERR_BUFFER_NOT_ENOUGH;
        goto error;
    }

    if (inputSize == 0) {
        LOGE("input is zero");
        ret =  RET_ERR_WRONG_INPUT_FORMAT;
        goto error;
    }

    memcpy(input, cmd->data, inputSize);

    //hex_print_tag_debug("input", input, inputSize);
    ret = unwrapInternalData(SECURE_OBJECT_TYPE_SERVICE_KEY, input, inputSize, output, &outputSize);
    if (ret == RET_SUCCESS) {
        //hex_print_tag_debug("output", output, outputSize);
        ret = parseSKPMServiceKey(output, outputSize);
        if (ret != RET_SUCCESS) {
            LOGE("parseSKPMServiceKey Failed.");
            goto error;
        } else {
            current_pos = 0;
            if (current_pos + 2 > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            memcpy(rsp->data + current_pos, &sDrkCertLen, 2);
            current_pos += 2;
            if (current_pos + sDrkCertLen > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            if (sDrkCertLen == 0) {
                LOGE("sDrkCert is zero");
                ret =  RET_ERR_WRONG_INPUT_FORMAT;
                goto error;
            }
            memcpy(rsp->data + current_pos, sDrkCert, sDrkCertLen);
            current_pos += sDrkCertLen;

            if (current_pos + 2 > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            memcpy(rsp->data + current_pos, &sServiceCertLen, 2);
            current_pos += 2;
            if (current_pos + sServiceCertLen > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            if (sServiceCertLen == 0) {
                LOGE("sServiceCert is zero");
                ret =  RET_ERR_WRONG_INPUT_FORMAT;
                goto error;
            }
            memcpy(rsp->data + current_pos, sServiceCert, sServiceCertLen);
            current_pos += sServiceCertLen;

            wrappedKeyInfoSize = sizeof(wrappedKeyInfo);
            if (wrapInternalData(SECURE_OBJECT_TYPE_TLS_SESSION_INFO, (uint8_t *)&sOtaTlsSession, sizeof(tls_session_info_t), wrappedKeyInfo, &wrappedKeyInfoSize) != STATUS_SUCCESS) {
                ret = RET_ERR_DATA_WRAPPING_FAIL;
                goto error;
            }

            if (current_pos + 4 > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            memcpy(rsp->data + current_pos, &wrappedKeyInfoSize, 4);
            current_pos += 4;
            if (current_pos + wrappedKeyInfoSize > sizeof(rsp->data)) {
                LOGE("rsp->data is over the buffer.");
                ret = RET_ERR_BUFFER_NOT_ENOUGH;
                goto error;
            }
            if (wrappedKeyInfoSize == 0) {
                LOGE("wrappedKeyInfo is zero");
                ret =  RET_ERR_WRONG_INPUT_FORMAT;
                goto error;
            }
            memcpy(rsp->data + current_pos, wrappedKeyInfo, wrappedKeyInfoSize);
            current_pos += wrappedKeyInfoSize;

            rsp->dataLen = current_pos;
            ret = RET_SUCCESS;
        }
    } else {
        LOGE("unwrapInternalData failed !!");
        ret = RET_ERR_DATA_UNWRAPPING_FAIL;
        goto error;
    }

error:
    secure_memclear(&sOtaTlsSession, sizeof(tls_session_info_t));
    LOGD("unwrapRewrappedSKPMServiceKey end : ret = %d", ret);

    rsp->ret = ret;
}

